AzerothCore 3.3.5a
OpenSource WoW Emulator
Loading...
Searching...
No Matches
WorldSession Class Reference

Player session in the World. More...

#include "WorldSession.h"

Classes

class  DosProtection
 

Public Member Functions

 WorldSession (uint32 id, std::string &&name, std::shared_ptr< WorldSocket > sock, AccountTypes sec, uint8 expansion, time_t mute_time, LocaleConstant locale, uint32 recruiter, bool isARecruiter, bool skipQueue, uint32 TotalTime)
 WorldSession constructor. More...
 
 ~WorldSession ()
 WorldSession destructor. More...
 
bool IsGMAccount () const
 
bool PlayerLoading () const
 
bool PlayerLogout () const
 
bool PlayerRecentlyLoggedOut () const
 
bool PlayerLogoutWithSave () const
 
void ReadAddonsInfo (ByteBuffer &data)
 
void SendAddonsInfo ()
 
void ReadMovementInfo (WorldPacket &data, MovementInfo *mi)
 
void WriteMovementInfo (WorldPacket *data, MovementInfo *mi)
 
void SendPacket (WorldPacket const *packet)
 Send a packet to the client. More...
 
void SendPetNameInvalid (uint32 error, std::string const &name, DeclinedName *declinedName)
 
void SendPartyResult (PartyOperation operation, std::string const &member, PartyResult res, uint32 val=0)
 
void SendAreaTriggerMessage (const char *Text,...) ATTR_PRINTF(2
 
void void SendAreaTriggerMessage (uint32 entry,...)
 
void SendSetPhaseShift (uint32 phaseShift)
 
void SendQueryTimeResponse ()
 
void SendAuthResponse (uint8 code, bool shortForm, uint32 queuePos=0)
 
void SendClientCacheVersion (uint32 version)
 
AccountTypes GetSecurity () const
 
bool CanSkipQueue () const
 
uint32 GetAccountId () const
 
PlayerGetPlayer () const
 
std::string const & GetPlayerName () const
 
std::string GetPlayerInfo () const
 
uint32 GetCurrentVendor () const
 
void SetCurrentVendor (uint32 vendorEntry)
 
ObjectGuid::LowType GetGuidLow () const
 Get player guid if available. Use for logging purposes only. More...
 
void SetSecurity (AccountTypes security)
 
std::string const & GetRemoteAddress ()
 
void SetPlayer (Player *player)
 
uint8 Expansion () const
 
void SetTotalTime (uint32 TotalTime)
 
uint32 GetTotalTime () const
 
void InitWarden (SessionKey const &, std::string const &os)
 
WardenGetWarden ()
 
void SetInQueue (bool state)
 Session in auth.queue currently. More...
 
bool isLogingOut () const
 Is the user engaged in a log out process? More...
 
void SetLogoutStartTime (time_t requestTime)
 Engage the logout process for the user. More...
 
bool ShouldLogOut (time_t currTime) const
 Is logout cooldown expired? More...
 
void LogoutPlayer (bool save)
 Log the player out More...
 
void KickPlayer (bool setKicked=true)
 
void KickPlayer (std::string const &reason, bool setKicked=true)
 Kick a player out of the World. More...
 
bool ValidateHyperlinksAndMaybeKick (std::string_view str)
 
bool DisallowHyperlinksAndMaybeKick (std::string_view str)
 
void QueuePacket (WorldPacket *new_packet)
 Add an incoming packet to the queue. More...
 
bool Update (uint32 diff, PacketFilter &updater)
 Update the WorldSession (triggered by World update) More...
 
void SendAuthWaitQueue (uint32 position)
 Handle the authentication waiting queue (to be completed) More...
 
void SendNameQueryOpcode (ObjectGuid guid)
 
void SendTrainerList (ObjectGuid guid)
 
void SendTrainerList (ObjectGuid guid, std::string const &strTitle)
 
void SendListInventory (ObjectGuid guid, uint32 vendorEntry=0)
 
void SendShowBank (ObjectGuid guid)
 
bool CanOpenMailBox (ObjectGuid guid)
 
void SendShowMailBox (ObjectGuid guid)
 
void SendTabardVendorActivate (ObjectGuid guid)
 
void SendSpiritResurrect ()
 
void SendBindPoint (Creature *npc)
 
void SendAttackStop (Unit const *enemy)
 
void SendBattleGroundList (ObjectGuid guid, BattlegroundTypeId bgTypeId=BATTLEGROUND_RB)
 
void SendTradeStatus (TradeStatus status)
 
void SendUpdateTrade (bool trader_data=true)
 
void SendCancelTrade ()
 
void SendPetitionQueryOpcode (ObjectGuid petitionguid)
 
void HandleClientCastFlags (WorldPacket &recvPacket, uint8 castFlags, SpellCastTargets &targets)
 
void SendPetNameQuery (ObjectGuid guid, uint32 petnumber)
 
void SendStablePet (ObjectGuid guid)
 
void SendStablePetCallback (ObjectGuid guid, PreparedQueryResult result)
 
void SendStableResult (uint8 guid)
 
bool CheckStableMaster (ObjectGuid guid)
 
AccountDataGetAccountData (AccountDataType type)
 
void SetAccountData (AccountDataType type, time_t tm, std::string const &data)
 
void SendAccountDataTimes (uint32 mask)
 
void LoadAccountData (PreparedQueryResult result, uint32 mask)
 
void LoadTutorialsData (PreparedQueryResult result)
 
void SendTutorialsData ()
 
void SaveTutorialsData (CharacterDatabaseTransaction trans)
 
uint32 GetTutorialInt (uint8 index) const
 
void SetTutorialInt (uint8 index, uint32 value)
 
void SendAuctionHello (ObjectGuid guid, Creature *unit)
 
void SendAuctionCommandResult (uint32 auctionId, uint32 Action, uint32 ErrorCode, uint32 bidError=0)
 
void SendAuctionBidderNotification (uint32 location, uint32 auctionId, ObjectGuid bidder, uint32 bidSum, uint32 diff, uint32 item_template)
 
void SendAuctionOwnerNotification (AuctionEntry *auction)
 
void SendEnchantmentLog (ObjectGuid target, ObjectGuid caster, uint32 itemId, uint32 enchantId)
 
void SendItemEnchantTimeUpdate (ObjectGuid Playerguid, ObjectGuid Itemguid, uint32 slot, uint32 Duration)
 
void SendTaxiStatus (ObjectGuid guid)
 
void SendTaxiMenu (Creature *unit)
 
void SendDoFlight (uint32 mountDisplayId, uint32 path, uint32 pathNode=0)
 
bool SendLearnNewTaxiNode (Creature *unit)
 
void SendDiscoverNewTaxiNode (uint32 nodeid)
 
void SendArenaTeamCommandResult (uint32 team_action, std::string const &team, std::string const &player, uint32 error_id=0)
 
void SendNotInArenaTeamPacket (uint8 type)
 
void SendPetitionShowList (ObjectGuid guid)
 
void BuildPartyMemberStatsChangedPacket (Player *player, WorldPacket *data)
 
void DoLootRelease (ObjectGuid lguid)
 
LocaleConstant GetSessionDbcLocale () const
 
LocaleConstant GetSessionDbLocaleIndex () const
 
char const * GetAcoreString (uint32 entry) const
 
std::string const * GetModuleString (std::string module, uint32 id) const
 
uint32 GetLatency () const
 
void SetLatency (uint32 latency)
 
void UpdateTimeOutTime (uint32 diff)
 
void ResetTimeOutTime (bool onlyActive)
 
bool IsConnectionIdle () const
 
uint32 GetRecruiterId () const
 
bool IsARecruiter () const
 
time_t GetCalendarEventCreationCooldown () const
 
void SetCalendarEventCreationCooldown (time_t cooldown)
 
void ResetTimeSync ()
 
void SendTimeSync ()
 
void Handle_NULL (WorldPacket &null)
 
void Handle_EarlyProccess (WorldPacket &recvPacket)
 
void Handle_ServerSide (WorldPacket &recvPacket)
 
void Handle_Deprecated (WorldPacket &recvPacket)
 
void HandleCharEnumOpcode (WorldPacket &recvPacket)
 
void HandleCharDeleteOpcode (WorldPacket &recvPacket)
 
void HandleCharCreateOpcode (WorldPacket &recvPacket)
 
void HandlePlayerLoginOpcode (WorldPacket &recvPacket)
 
void HandleCharEnum (PreparedQueryResult result)
 
void HandlePlayerLoginFromDB (LoginQueryHolder const &holder)
 
void HandlePlayerLoginToCharInWorld (Player *pCurrChar)
 
void HandlePlayerLoginToCharOutOfWorld (Player *pCurrChar)
 
void HandleCharFactionOrRaceChange (WorldPacket &recvData)
 
void HandleCharFactionOrRaceChangeCallback (std::shared_ptr< CharacterFactionChangeInfo > factionChangeInfo, PreparedQueryResult result)
 
void SendCharCreate (ResponseCodes result)
 
void SendCharDelete (ResponseCodes result)
 
void SendCharRename (ResponseCodes result, CharacterRenameInfo const *renameInfo)
 
void SendCharCustomize (ResponseCodes result, CharacterCustomizeInfo const *customizeInfo)
 
void SendCharFactionChange (ResponseCodes result, CharacterFactionChangeInfo const *factionChangeInfo)
 
void SendSetPlayerDeclinedNamesResult (DeclinedNameResult result, ObjectGuid guid)
 
void HandlePlayedTime (WorldPackets::Character::PlayedTimeClient &packet)
 
void HandleMoveUnRootAck (WorldPacket &recvPacket)
 
void HandleMoveRootAck (WorldPacket &recvPacket)
 
void HandleInspectOpcode (WorldPacket &recvPacket)
 
void HandleInspectHonorStatsOpcode (WorldPacket &recvPacket)
 
void HandleMoveWaterWalkAck (WorldPacket &recvPacket)
 
void HandleFeatherFallAck (WorldPacket &recvData)
 
void HandleMoveHoverAck (WorldPacket &recvData)
 
void HandleMountSpecialAnimOpcode (WorldPacket &recvdata)
 
void HandleShowingHelmOpcode (WorldPackets::Character::ShowingHelm &packet)
 
void HandleShowingCloakOpcode (WorldPackets::Character::ShowingCloak &packet)
 
void HandleRepairItemOpcode (WorldPacket &recvPacket)
 
void HandleMoveKnockBackAck (WorldPacket &recvPacket)
 
void HandleMoveTeleportAck (WorldPacket &recvPacket)
 
void HandleForceSpeedChangeAck (WorldPacket &recvData)
 
void HandleRepopRequestOpcode (WorldPacket &recvPacket)
 
void HandleAutostoreLootItemOpcode (WorldPacket &recvPacket)
 
void HandleLootMoneyOpcode (WorldPacket &recvPacket)
 
void HandleLootOpcode (WorldPacket &recvPacket)
 
void HandleLootReleaseOpcode (WorldPacket &recvPacket)
 
void HandleLootMasterGiveOpcode (WorldPacket &recvPacket)
 
void HandleWhoOpcode (WorldPacket &recvPacket)
 
void HandleLogoutRequestOpcode (WorldPackets::Character::LogoutRequest &logoutRequest)
 
void HandlePlayerLogoutOpcode (WorldPackets::Character::PlayerLogout &playerLogout)
 
void HandleLogoutCancelOpcode (WorldPackets::Character::LogoutCancel &logoutCancel)
 
void HandleGMTicketCreateOpcode (WorldPacket &recvPacket)
 
void HandleGMTicketUpdateOpcode (WorldPacket &recvPacket)
 
void HandleGMTicketDeleteOpcode (WorldPacket &recvPacket)
 
void HandleGMTicketGetTicketOpcode (WorldPacket &recvPacket)
 
void HandleGMTicketSystemStatusOpcode (WorldPacket &recvPacket)
 
void HandleGMSurveySubmit (WorldPacket &recvPacket)
 
void HandleReportLag (WorldPacket &recvPacket)
 
void HandleGMResponseResolve (WorldPacket &recvPacket)
 
void HandleTogglePvP (WorldPacket &recvPacket)
 
void HandleZoneUpdateOpcode (WorldPacket &recvPacket)
 
void HandleSetSelectionOpcode (WorldPacket &recvPacket)
 
void HandleStandStateChangeOpcode (WorldPacket &recvPacket)
 
void HandleEmoteOpcode (WorldPackets::Chat::EmoteClient &packet)
 
void HandleContactListOpcode (WorldPacket &recvPacket)
 
void HandleAddFriendOpcode (WorldPacket &recvPacket)
 
void HandleDelFriendOpcode (WorldPacket &recvPacket)
 
void HandleAddIgnoreOpcode (WorldPacket &recvPacket)
 
void HandleDelIgnoreOpcode (WorldPacket &recvPacket)
 
void HandleSetContactNotesOpcode (WorldPacket &recvPacket)
 
void HandleBugOpcode (WorldPacket &recvPacket)
 
void HandleSetAmmoOpcode (WorldPacket &recvPacket)
 
void HandleItemNameQueryOpcode (WorldPacket &recvPacket)
 
void HandleAreaTriggerOpcode (WorldPacket &recvPacket)
 
void HandleSetFactionAtWar (WorldPacket &recvData)
 
void HandleSetFactionCheat (WorldPacket &recvData)
 
void HandleSetWatchedFactionOpcode (WorldPacket &recvData)
 
void HandleSetFactionInactiveOpcode (WorldPacket &recvData)
 
void HandleUpdateAccountData (WorldPacket &recvPacket)
 
void HandleRequestAccountData (WorldPacket &recvPacket)
 
void HandleSetActionButtonOpcode (WorldPacket &recvPacket)
 
void HandleGameObjectUseOpcode (WorldPacket &recPacket)
 
void HandleGameobjectReportUse (WorldPacket &recvPacket)
 
void HandleNameQueryOpcode (WorldPacket &recvPacket)
 
void HandleQueryTimeOpcode (WorldPacket &recvPacket)
 
void HandleCreatureQueryOpcode (WorldPacket &recvPacket)
 Only static data is sent in this packet !!! More...
 
void HandleGameObjectQueryOpcode (WorldPacket &recvPacket)
 Only static data is sent in this packet !!! More...
 
void HandleMoveWorldportAckOpcode (WorldPacket &recvPacket)
 
void HandleMoveWorldportAck ()
 
void HandleMovementOpcodes (WorldPacket &recvPacket)
 
void HandleSetActiveMoverOpcode (WorldPacket &recvData)
 
void HandleMoveNotActiveMover (WorldPacket &recvData)
 
void HandleDismissControlledVehicle (WorldPacket &recvData)
 
void HandleRequestVehicleExit (WorldPacket &recvData)
 
void HandleChangeSeatsOnControlledVehicle (WorldPacket &recvData)
 
void HandleMoveTimeSkippedOpcode (WorldPacket &recvData)
 
void HandleRequestRaidInfoOpcode (WorldPacket &recvData)
 
void HandleBattlefieldStatusOpcode (WorldPacket &recvData)
 
void HandleGroupInviteOpcode (WorldPacket &recvPacket)
 
void HandleGroupAcceptOpcode (WorldPacket &recvPacket)
 
void HandleGroupDeclineOpcode (WorldPacket &recvPacket)
 
void HandleGroupUninviteOpcode (WorldPacket &recvPacket)
 
void HandleGroupUninviteGuidOpcode (WorldPacket &recvPacket)
 
void HandleGroupSetLeaderOpcode (WorldPacket &recvPacket)
 
void HandleGroupDisbandOpcode (WorldPacket &recvPacket)
 
void HandleOptOutOfLootOpcode (WorldPacket &recvData)
 
void HandleLootMethodOpcode (WorldPacket &recvPacket)
 
void HandleLootRoll (WorldPacket &recvData)
 
void HandleRequestPartyMemberStatsOpcode (WorldPacket &recvData)
 
void HandleGroupSwapSubGroupOpcode (WorldPacket &recvData)
 
void HandleRaidTargetUpdateOpcode (WorldPacket &recvData)
 
void HandleRaidReadyCheckOpcode (WorldPacket &recvData)
 
void HandleRaidReadyCheckFinishedOpcode (WorldPacket &recvData)
 
void HandleGroupRaidConvertOpcode (WorldPacket &recvData)
 
void HandleGroupChangeSubGroupOpcode (WorldPacket &recvData)
 
void HandleGroupAssistantLeaderOpcode (WorldPacket &recvData)
 
void HandlePartyAssignmentOpcode (WorldPacket &recvData)
 
void HandlePetitionBuyOpcode (WorldPacket &recvData)
 
void HandlePetitionShowSignOpcode (WorldPacket &recvData)
 
void HandlePetitionQueryOpcode (WorldPacket &recvData)
 
void HandlePetitionRenameOpcode (WorldPacket &recvData)
 
void HandlePetitionSignOpcode (WorldPacket &recvData)
 
void HandlePetitionDeclineOpcode (WorldPacket &recvData)
 
void HandleOfferPetitionOpcode (WorldPacket &recvData)
 
void HandleTurnInPetitionOpcode (WorldPacket &recvData)
 
void HandleGuildQueryOpcode (WorldPackets::Guild::QueryGuildInfo &query)
 
void HandleGuildCreateOpcode (WorldPackets::Guild::GuildCreate &packet)
 
void HandleGuildInviteOpcode (WorldPackets::Guild::GuildInviteByName &packet)
 
void HandleGuildRemoveOpcode (WorldPackets::Guild::GuildOfficerRemoveMember &packet)
 
void HandleGuildAcceptOpcode (WorldPackets::Guild::AcceptGuildInvite &invite)
 
void HandleGuildDeclineOpcode (WorldPackets::Guild::GuildDeclineInvitation &decline)
 
void HandleGuildInfoOpcode (WorldPackets::Guild::GuildGetInfo &packet)
 
void HandleGuildEventLogQueryOpcode (WorldPackets::Guild::GuildEventLogQuery &packet)
 
void HandleGuildRosterOpcode (WorldPackets::Guild::GuildGetRoster &packet)
 
void HandleGuildPromoteOpcode (WorldPackets::Guild::GuildPromoteMember &promote)
 
void HandleGuildDemoteOpcode (WorldPackets::Guild::GuildDemoteMember &demote)
 
void HandleGuildLeaveOpcode (WorldPackets::Guild::GuildLeave &leave)
 
void HandleGuildDisbandOpcode (WorldPackets::Guild::GuildDelete &packet)
 
void HandleGuildLeaderOpcode (WorldPackets::Guild::GuildSetGuildMaster &packet)
 
void HandleGuildMOTDOpcode (WorldPackets::Guild::GuildUpdateMotdText &packet)
 
void HandleGuildSetPublicNoteOpcode (WorldPackets::Guild::GuildSetMemberNote &packet)
 
void HandleGuildSetOfficerNoteOpcode (WorldPackets::Guild::GuildSetMemberNote &packet)
 
void HandleGuildRankOpcode (WorldPackets::Guild::GuildSetRankPermissions &packet)
 
void HandleGuildAddRankOpcode (WorldPackets::Guild::GuildAddRank &packet)
 
void HandleGuildDelRankOpcode (WorldPackets::Guild::GuildDeleteRank &packet)
 
void HandleGuildChangeInfoTextOpcode (WorldPackets::Guild::GuildUpdateInfoText &packet)
 
void HandleSaveGuildEmblemOpcode (WorldPackets::Guild::SaveGuildEmblem &packet)
 
void HandleTaxiNodeStatusQueryOpcode (WorldPacket &recvPacket)
 
void HandleTaxiQueryAvailableNodes (WorldPacket &recvPacket)
 
void HandleActivateTaxiOpcode (WorldPacket &recvPacket)
 
void HandleActivateTaxiExpressOpcode (WorldPacket &recvPacket)
 
void HandleMoveSplineDoneOpcode (WorldPacket &recvPacket)
 
void SendActivateTaxiReply (ActivateTaxiReply reply)
 
void HandleTabardVendorActivateOpcode (WorldPacket &recvPacket)
 
void HandleTrainerListOpcode (WorldPacket &recvPacket)
 
void HandleTrainerBuySpellOpcode (WorldPacket &recvPacket)
 
void HandlePetitionShowListOpcode (WorldPacket &recvPacket)
 
void HandleGossipHelloOpcode (WorldPacket &recvPacket)
 
void HandleGossipSelectOptionOpcode (WorldPacket &recvPacket)
 
void HandleSpiritHealerActivateOpcode (WorldPacket &recvPacket)
 
void HandleNpcTextQueryOpcode (WorldPacket &recvPacket)
 
void HandleBinderActivateOpcode (WorldPacket &recvPacket)
 
void HandleListStabledPetsOpcode (WorldPacket &recvPacket)
 
void HandleStablePet (WorldPacket &recvPacket)
 
void HandleUnstablePet (WorldPacket &recvPacket)
 
void HandleBuyStableSlot (WorldPacket &recvPacket)
 
void HandleStableRevivePet (WorldPacket &recvPacket)
 
void HandleStableSwapPet (WorldPacket &recvPacket)
 
void HandleOpenWrappedItemCallback (uint8 bagIndex, uint8 slot, ObjectGuid::LowType itemLowGUID, PreparedQueryResult result)
 
void HandleLoadActionsSwitchSpec (PreparedQueryResult result)
 
void HandleCharacterAuraFrozen (PreparedQueryResult result)
 
void HandleDuelAcceptedOpcode (WorldPacket &recvPacket)
 
void HandleDuelCancelledOpcode (WorldPacket &recvPacket)
 
void HandleAcceptTradeOpcode (WorldPacket &recvPacket)
 
void HandleBeginTradeOpcode (WorldPacket &recvPacket)
 
void HandleBusyTradeOpcode (WorldPacket &recvPacket)
 
void HandleCancelTradeOpcode (WorldPacket &recvPacket)
 
void HandleClearTradeItemOpcode (WorldPacket &recvPacket)
 
void HandleIgnoreTradeOpcode (WorldPacket &recvPacket)
 
void HandleInitiateTradeOpcode (WorldPacket &recvPacket)
 
void HandleSetTradeGoldOpcode (WorldPacket &recvPacket)
 
void HandleSetTradeItemOpcode (WorldPacket &recvPacket)
 
void HandleUnacceptTradeOpcode (WorldPacket &recvPacket)
 
void HandleAuctionHelloOpcode (WorldPacket &recvPacket)
 
void HandleAuctionListItems (WorldPacket &recvData)
 
void HandleAuctionListBidderItems (WorldPacket &recvData)
 
void HandleAuctionSellItem (WorldPacket &recvData)
 
void HandleAuctionRemoveItem (WorldPacket &recvData)
 
void HandleAuctionListOwnerItems (WorldPacket &recvData)
 
void HandleAuctionListOwnerItemsEvent (ObjectGuid creatureGuid)
 
void HandleAuctionPlaceBid (WorldPacket &recvData)
 
void HandleAuctionListPendingSales (WorldPacket &recvData)
 
void HandleBankerActivateOpcode (WorldPacket &recvData)
 
void HandleAutoBankItemOpcode (WorldPackets::Bank::AutoBankItem &packet)
 
void HandleAutoStoreBankItemOpcode (WorldPackets::Bank::AutoStoreBankItem &packet)
 
void HandleBuyBankSlotOpcode (WorldPackets::Bank::BuyBankSlot &buyBankSlot)
 
void HandleGetMailList (WorldPacket &recvData)
 
void HandleSendMail (WorldPacket &recvData)
 
void HandleMailTakeMoney (WorldPacket &recvData)
 
void HandleMailTakeItem (WorldPacket &recvData)
 
void HandleMailMarkAsRead (WorldPacket &recvData)
 
void HandleMailReturnToSender (WorldPacket &recvData)
 
void HandleMailDelete (WorldPacket &recvData)
 
void HandleItemTextQuery (WorldPacket &recvData)
 
void HandleMailCreateTextItem (WorldPacket &recvData)
 
void HandleQueryNextMailTime (WorldPacket &recvData)
 
void HandleCancelChanneling (WorldPacket &recvData)
 
void HandleSplitItemOpcode (WorldPacket &recvPacket)
 
void HandleSwapInvItemOpcode (WorldPacket &recvPacket)
 
void HandleDestroyItemOpcode (WorldPacket &recvPacket)
 
void HandleAutoEquipItemOpcode (WorldPacket &recvPacket)
 
void HandleItemQuerySingleOpcode (WorldPacket &recvPacket)
 
void HandleSellItemOpcode (WorldPacket &recvPacket)
 
void HandleBuyItemInSlotOpcode (WorldPacket &recvPacket)
 
void HandleBuyItemOpcode (WorldPacket &recvPacket)
 
void HandleListInventoryOpcode (WorldPacket &recvPacket)
 
void HandleAutoStoreBagItemOpcode (WorldPacket &recvPacket)
 
void HandleReadItem (WorldPacket &recvPacket)
 
void HandleAutoEquipItemSlotOpcode (WorldPacket &recvPacket)
 
void HandleSwapItem (WorldPacket &recvPacket)
 
void HandleBuybackItem (WorldPacket &recvPacket)
 
void HandleWrapItemOpcode (WorldPacket &recvPacket)
 
void HandleAttackSwingOpcode (WorldPacket &recvPacket)
 
void HandleAttackStopOpcode (WorldPacket &recvPacket)
 
void HandleSetSheathedOpcode (WorldPackets::Combat::SetSheathed &packet)
 
void HandleUseItemOpcode (WorldPacket &recvPacket)
 
void HandleOpenItemOpcode (WorldPacket &recvPacket)
 
void HandleCastSpellOpcode (WorldPacket &recvPacket)
 
void HandleCancelCastOpcode (WorldPacket &recvPacket)
 
void HandleCancelAuraOpcode (WorldPacket &recvPacket)
 
void HandleCancelGrowthAuraOpcode (WorldPacket &recvPacket)
 
void HandleCancelAutoRepeatSpellOpcode (WorldPacket &recvPacket)
 
void HandleLearnTalentOpcode (WorldPacket &recvPacket)
 
void HandleLearnPreviewTalents (WorldPacket &recvPacket)
 
void HandleTalentWipeConfirmOpcode (WorldPacket &recvPacket)
 
void HandleUnlearnSkillOpcode (WorldPacket &recvPacket)
 
void HandleQuestgiverStatusQueryOpcode (WorldPacket &recvPacket)
 
void HandleQuestgiverStatusMultipleQuery (WorldPacket &recvPacket)
 
void HandleQuestgiverHelloOpcode (WorldPacket &recvPacket)
 
void HandleQuestgiverAcceptQuestOpcode (WorldPacket &recvPacket)
 
void HandleQuestgiverQueryQuestOpcode (WorldPacket &recvPacket)
 
void HandleQuestgiverChooseRewardOpcode (WorldPacket &recvPacket)
 
void HandleQuestgiverRequestRewardOpcode (WorldPacket &recvPacket)
 
void HandleQuestQueryOpcode (WorldPacket &recvPacket)
 
void HandleQuestgiverCancel (WorldPacket &recvData)
 
void HandleQuestLogSwapQuest (WorldPacket &recvData)
 
void HandleQuestLogRemoveQuest (WorldPacket &recvData)
 
void HandleQuestConfirmAccept (WorldPacket &recvData)
 
void HandleQuestgiverCompleteQuest (WorldPacket &recvData)
 
void HandleQuestgiverQuestAutoLaunch (WorldPacket &recvPacket)
 
void HandlePushQuestToParty (WorldPacket &recvPacket)
 
void HandleQuestPushResult (WorldPacket &recvPacket)
 
void HandleMessagechatOpcode (WorldPacket &recvPacket)
 
void SendPlayerNotFoundNotice (std::string const &name)
 
void SendPlayerAmbiguousNotice (std::string const &name)
 
void SendWrongFactionNotice ()
 
void SendChatRestrictedNotice (ChatRestrictionType restriction)
 
void HandleTextEmoteOpcode (WorldPacket &recvPacket)
 
void HandleChatIgnoredOpcode (WorldPacket &recvPacket)
 
void HandleReclaimCorpseOpcode (WorldPacket &recvPacket)
 
void HandleCorpseQueryOpcode (WorldPacket &recvPacket)
 
void HandleCorpseMapPositionQuery (WorldPacket &recvPacket)
 
void HandleResurrectResponseOpcode (WorldPacket &recvPacket)
 
void HandleSummonResponseOpcode (WorldPacket &recvData)
 
void HandleJoinChannel (WorldPacket &recvPacket)
 
void HandleLeaveChannel (WorldPacket &recvPacket)
 
void HandleChannelList (WorldPacket &recvPacket)
 
void HandleChannelPassword (WorldPacket &recvPacket)
 
void HandleChannelSetOwner (WorldPacket &recvPacket)
 
void HandleChannelOwner (WorldPacket &recvPacket)
 
void HandleChannelModerator (WorldPacket &recvPacket)
 
void HandleChannelUnmoderator (WorldPacket &recvPacket)
 
void HandleChannelMute (WorldPacket &recvPacket)
 
void HandleChannelUnmute (WorldPacket &recvPacket)
 
void HandleChannelInvite (WorldPacket &recvPacket)
 
void HandleChannelKick (WorldPacket &recvPacket)
 
void HandleChannelBan (WorldPacket &recvPacket)
 
void HandleChannelUnban (WorldPacket &recvPacket)
 
void HandleChannelAnnouncements (WorldPacket &recvPacket)
 
void HandleChannelModerateOpcode (WorldPacket &recvPacket)
 
void HandleChannelDeclineInvite (WorldPacket &recvPacket)
 
void HandleChannelDisplayListQuery (WorldPacket &recvPacket)
 
void HandleGetChannelMemberCount (WorldPacket &recvPacket)
 
void HandleSetChannelWatch (WorldPacket &recvPacket)
 
void HandleClearChannelWatch (WorldPacket &recvPacket)
 
void HandleCompleteCinematic (WorldPacket &recvPacket)
 
void HandleNextCinematicCamera (WorldPacket &recvPacket)
 
void HandlePageTextQueryOpcode (WorldPacket &recvPacket)
 Only static data is sent in this packet !!! More...
 
void HandleTutorialFlag (WorldPacket &recvData)
 
void HandleTutorialClear (WorldPacket &recvData)
 
void HandleTutorialReset (WorldPacket &recvData)
 
void HandlePetAction (WorldPacket &recvData)
 
void HandlePetStopAttack (WorldPackets::Pet::PetStopAttack &packet)
 
void HandlePetActionHelper (Unit *pet, ObjectGuid guid1, uint32 spellid, uint16 flag, ObjectGuid guid2)
 
void HandlePetNameQuery (WorldPacket &recvData)
 
void HandlePetSetAction (WorldPacket &recvData)
 
void HandlePetAbandon (WorldPackets::Pet::PetAbandon &packet)
 
void HandlePetRename (WorldPacket &recvData)
 
void HandlePetCancelAuraOpcode (WorldPacket &recvPacket)
 
void HandlePetSpellAutocastOpcode (WorldPackets::Pet::PetSpellAutocast &packet)
 
void HandlePetCastSpellOpcode (WorldPacket &recvPacket)
 
void HandlePetLearnTalent (WorldPacket &recvPacket)
 
void HandleLearnPreviewTalentsPet (WorldPacket &recvPacket)
 
void HandleSetActionBarToggles (WorldPacket &recvData)
 
void HandleCharRenameOpcode (WorldPacket &recvData)
 
void HandleCharRenameCallBack (std::shared_ptr< CharacterRenameInfo > renameInfo, PreparedQueryResult result)
 
void HandleSetPlayerDeclinedNames (WorldPacket &recvData)
 
void HandleTotemDestroyed (WorldPackets::Totem::TotemDestroyed &totemDestroyed)
 
void HandleDismissCritter (WorldPackets::Pet::DismissCritter &dismissCritter)
 
void HandleBattlemasterHelloOpcode (WorldPacket &recvData)
 
void HandleBattlemasterJoinOpcode (WorldPacket &recvData)
 
void HandleBattlegroundPlayerPositionsOpcode (WorldPacket &recvData)
 
void HandlePVPLogDataOpcode (WorldPacket &recvData)
 
void HandleBattleFieldPortOpcode (WorldPacket &recvData)
 
void HandleBattlefieldListOpcode (WorldPacket &recvData)
 
void HandleBattlefieldLeaveOpcode (WorldPacket &recvData)
 
void HandleBattlemasterJoinArena (WorldPacket &recvData)
 
void HandleReportPvPAFK (WorldPacket &recvData)
 
void HandleWardenDataOpcode (WorldPacket &recvData)
 
void HandleWorldTeleportOpcode (WorldPacket &recvData)
 
void HandleMinimapPingOpcode (WorldPacket &recvData)
 
void HandleRandomRollOpcode (WorldPackets::Misc::RandomRollClient &packet)
 
void HandleFarSightOpcode (WorldPacket &recvData)
 
void HandleSetDungeonDifficultyOpcode (WorldPacket &recvData)
 
void HandleSetRaidDifficultyOpcode (WorldPacket &recvData)
 
void HandleMoveSetCanFlyAckOpcode (WorldPacket &recvData)
 
void HandleSetTitleOpcode (WorldPacket &recvData)
 
void HandleRealmSplitOpcode (WorldPacket &recvData)
 
void HandleTimeSyncResp (WorldPacket &recvData)
 
void HandleWhoisOpcode (WorldPacket &recvData)
 
void HandleResetInstancesOpcode (WorldPacket &recvData)
 
void HandleHearthAndResurrect (WorldPacket &recvData)
 
void HandleInstanceLockResponse (WorldPacket &recvPacket)
 
void HandleUpdateMissileTrajectory (WorldPacket &recvPacket)
 
void SendBfInvitePlayerToWar (uint32 battleId, uint32 zoneId, uint32 time)
 
void SendBfInvitePlayerToQueue (uint32 battleId)
 
void SendBfQueueInviteResponse (uint32 battleId, uint32 zoneId, bool canQueue=true, bool full=false)
 
void SendBfEntered (uint32 battleId)
 
void SendBfLeaveMessage (uint32 battleId, BFLeaveReason reason=BF_LEAVE_REASON_EXITED)
 
void HandleBfQueueInviteResponse (WorldPacket &recvData)
 
void HandleBfEntryInviteResponse (WorldPacket &recvData)
 
void HandleBfExitRequest (WorldPacket &recvData)
 
void HandleLfgSetCommentOpcode (WorldPacket &recvData)
 
void HandleLfgPlayerLockInfoRequestOpcode (WorldPacket &recvData)
 
void HandleLfgPartyLockInfoRequestOpcode (WorldPacket &recvData)
 
void HandleLfgJoinOpcode (WorldPackets::LFG::LFGJoin &lfgJoin)
 
void HandleLfgLeaveOpcode (WorldPackets::LFG::LFGLeave &lfgleave)
 
void HandleLfgSetRolesOpcode (WorldPacket &recvData)
 
void HandleLfgProposalResultOpcode (WorldPacket &recvData)
 
void HandleLfgSetBootVoteOpcode (WorldPacket &recvData)
 
void HandleLfgTeleportOpcode (WorldPacket &recvData)
 
void HandleLfrSearchJoinOpcode (WorldPacket &recvData)
 
void HandleLfrSearchLeaveOpcode (WorldPacket &recvData)
 
void HandleLfgGetStatus (WorldPacket &recvData)
 
void SendLfgUpdatePlayer (lfg::LfgUpdateData const &updateData)
 
void SendLfgUpdateParty (lfg::LfgUpdateData const &updateData)
 
void SendLfgRoleChosen (ObjectGuid guid, uint8 roles)
 
void SendLfgRoleCheckUpdate (lfg::LfgRoleCheck const &pRoleCheck)
 
void SendLfgLfrList (bool update)
 
void SendLfgJoinResult (lfg::LfgJoinResultData const &joinData)
 
void SendLfgQueueStatus (lfg::LfgQueueStatusData const &queueData)
 
void SendLfgPlayerReward (lfg::LfgPlayerRewardData const &lfgPlayerRewardData)
 
void SendLfgBootProposalUpdate (lfg::LfgPlayerBoot const &boot)
 
void SendLfgUpdateProposal (lfg::LfgProposal const &proposal)
 
void SendLfgDisabled ()
 
void SendLfgOfferContinue (uint32 dungeonEntry)
 
void SendLfgTeleportError (uint8 err)
 
void HandleInspectArenaTeamsOpcode (WorldPacket &recvData)
 
void HandleArenaTeamQueryOpcode (WorldPacket &recvData)
 
void HandleArenaTeamRosterOpcode (WorldPacket &recvData)
 
void HandleArenaTeamInviteOpcode (WorldPacket &recvData)
 
void HandleArenaTeamAcceptOpcode (WorldPacket &recvData)
 
void HandleArenaTeamDeclineOpcode (WorldPacket &recvData)
 
void HandleArenaTeamLeaveOpcode (WorldPacket &recvData)
 
void HandleArenaTeamRemoveOpcode (WorldPacket &recvData)
 
void HandleArenaTeamDisbandOpcode (WorldPacket &recvData)
 
void HandleArenaTeamLeaderOpcode (WorldPacket &recvData)
 
void HandleAreaSpiritHealerQueryOpcode (WorldPacket &recvData)
 
void HandleAreaSpiritHealerQueueOpcode (WorldPacket &recvData)
 
void HandleCancelMountAuraOpcode (WorldPacket &recvData)
 
void HandleSelfResOpcode (WorldPacket &recvData)
 
void HandleComplainOpcode (WorldPacket &recvData)
 
void HandleRequestPetInfo (WorldPackets::Pet::RequestPetInfo &packet)
 
void HandleSocketOpcode (WorldPacket &recvData)
 
void HandleCancelTempEnchantmentOpcode (WorldPacket &recvData)
 
void HandleItemRefundInfoRequest (WorldPacket &recvData)
 
void HandleItemRefund (WorldPacket &recvData)
 
void HandleChannelVoiceOnOpcode (WorldPacket &recvData)
 
void HandleVoiceSessionEnableOpcode (WorldPacket &recvData)
 
void HandleSetActiveVoiceChannel (WorldPacket &recvData)
 
void HandleSetTaxiBenchmarkOpcode (WorldPacket &recvData)
 
void HandleGuildPermissions (WorldPackets::Guild::GuildPermissionsQuery &packet)
 
void HandleGuildBankMoneyWithdrawn (WorldPackets::Guild::GuildBankRemainingWithdrawMoneyQuery &packet)
 
void HandleGuildBankerActivate (WorldPackets::Guild::GuildBankActivate &packet)
 
void HandleGuildBankQueryTab (WorldPackets::Guild::GuildBankQueryTab &packet)
 
void HandleGuildBankLogQuery (WorldPackets::Guild::GuildBankLogQuery &packet)
 
void HandleGuildBankDepositMoney (WorldPackets::Guild::GuildBankDepositMoney &packet)
 
void HandleGuildBankWithdrawMoney (WorldPackets::Guild::GuildBankWithdrawMoney &packet)
 
void HandleGuildBankSwapItems (WorldPackets::Guild::GuildBankSwapItems &packet)
 
void HandleGuildBankUpdateTab (WorldPackets::Guild::GuildBankUpdateTab &packet)
 
void HandleGuildBankBuyTab (WorldPackets::Guild::GuildBankBuyTab &packet)
 
void HandleQueryGuildBankTabText (WorldPackets::Guild::GuildBankTextQuery &packet)
 
void HandleSetGuildBankTabText (WorldPackets::Guild::GuildBankSetTabText &packet)
 
void HandleGrantLevel (WorldPacket &recvData)
 
void HandleAcceptGrantLevel (WorldPacket &recvData)
 
void HandleCalendarGetCalendar (WorldPacket &recvData)
 
void HandleCalendarGetEvent (WorldPacket &recvData)
 
void HandleCalendarGuildFilter (WorldPacket &recvData)
 
void HandleCalendarArenaTeam (WorldPacket &recvData)
 
void HandleCalendarAddEvent (WorldPacket &recvData)
 
void HandleCalendarUpdateEvent (WorldPacket &recvData)
 
void HandleCalendarRemoveEvent (WorldPacket &recvData)
 
void HandleCalendarCopyEvent (WorldPacket &recvData)
 
void HandleCalendarEventInvite (WorldPacket &recvData)
 
void HandleCalendarEventRsvp (WorldPacket &recvData)
 
void HandleCalendarEventRemoveInvite (WorldPacket &recvData)
 
void HandleCalendarEventStatus (WorldPacket &recvData)
 
void HandleCalendarEventModeratorStatus (WorldPacket &recvData)
 
void HandleCalendarComplain (WorldPacket &recvData)
 
void HandleCalendarGetNumPending (WorldPacket &recvData)
 
void HandleCalendarEventSignup (WorldPacket &recvData)
 
void SendCalendarRaidLockout (InstanceSave const *save, bool add)
 
void SendCalendarRaidLockoutUpdated (InstanceSave const *save, bool isExtended)
 
void HandleSetSavedInstanceExtend (WorldPacket &recvData)
 
void HandleSpellClick (WorldPacket &recvData)
 
void HandleMirrorImageDataRequest (WorldPacket &recvData)
 
void HandleAlterAppearance (WorldPacket &recvData)
 
void HandleRemoveGlyph (WorldPacket &recvData)
 
void HandleCharCustomize (WorldPacket &recvData)
 
void HandleCharCustomizeCallback (std::shared_ptr< CharacterCustomizeInfo > customizeInfo, PreparedQueryResult result)
 
void HandleQueryInspectAchievements (WorldPacket &recvData)
 
void HandleEquipmentSetSave (WorldPacket &recvData)
 
void HandleEquipmentSetDelete (WorldPacket &recvData)
 
void HandleEquipmentSetUse (WorldPacket &recvData)
 
void HandleWorldStateUITimerUpdate (WorldPacket &recvData)
 
void HandleReadyForAccountDataTimes (WorldPacket &recvData)
 
void HandleQueryQuestsCompleted (WorldPacket &recvData)
 
void HandleQuestPOIQuery (WorldPacket &recvData)
 
void HandleEjectPassenger (WorldPacket &data)
 
void HandleEnterPlayerVehicle (WorldPacket &data)
 
void HandleUpdateProjectilePosition (WorldPacket &recvPacket)
 
void HandleTeleportTimeout (bool updateInSessions)
 
bool HandleSocketClosed ()
 
void SetOfflineTime (uint32 time)
 
uint32 GetOfflineTime () const
 
bool IsKicked () const
 
void SetKicked (bool val)
 
bool IsSocketClosed () const
 
QueryCallbackProcessorGetQueryProcessor ()
 
TransactionCallbackAddTransactionCallback (TransactionCallback &&callback)
 
SQLQueryHolderCallbackAddQueryHolderCallback (SQLQueryHolderCallback &&callback)
 
void InitializeSession ()
 
void InitializeSessionCallback (CharacterDatabaseQueryHolder const &realmHolder, uint32 clientCacheVersion)
 

Public Attributes

time_t m_muteTime
 
std::atomic< time_t > m_timeOutTime
 
Milliseconds _lastAuctionListItemsMSTime
 
Milliseconds _lastAuctionListOwnerItemsMSTime
 

Protected Attributes

class WorldSession::DosProtection AntiDOS
 

Private Types

typedef std::list< AddonInfoAddonsList
 

Private Member Functions

void ProcessQueryCallbacks ()
 
void moveItems (Item *myItems[], Item *hisItems[])
 
bool CanUseBank (ObjectGuid bankerGUID=ObjectGuid::Empty) const
 
bool recoveryItem (Item *pItem)
 
void LogUnexpectedOpcode (WorldPacket *packet, char const *status, const char *reason)
 Logging helper for unexpected opcodes. More...
 
void LogUnprocessedTail (WorldPacket *packet)
 Logging helper for unexpected opcodes. More...
 
bool IsLegitCharacterForAccount (ObjectGuid guid)
 
void ComputeNewClockDelta ()
 
 WorldSession (WorldSession const &right)=delete
 
WorldSessionoperator= (WorldSession const &right)=delete
 

Private Attributes

QueryCallbackProcessor _queryProcessor
 
AsyncCallbackProcessor< TransactionCallback_transactionCallbacks
 
AsyncCallbackProcessor< SQLQueryHolderCallback_queryHolderProcessor
 
GuidSet _legitCharacters
 
ObjectGuid::LowType m_GUIDLow
 
Player_player
 
std::shared_ptr< WorldSocketm_Socket
 
std::string m_Address
 
AccountTypes _security
 
bool _skipQueue
 
uint32 _accountId
 
std::string _accountName
 
uint8 m_expansion
 
uint32 m_total_time
 
std::unique_ptr< Warden_warden
 
time_t _logoutTime
 
bool m_inQueue
 
bool m_playerLoading
 
bool m_playerLogout
 
bool m_playerRecentlyLogout
 
bool m_playerSave
 
LocaleConstant m_sessionDbcLocale
 
LocaleConstant m_sessionDbLocaleIndex
 
std::atomic< uint32m_latency
 
AccountData m_accountData [NUM_ACCOUNT_DATA_TYPES]
 
uint32 m_Tutorials [MAX_ACCOUNT_TUTORIAL_VALUES]
 
bool m_TutorialsChanged
 
AddonsList m_addonsList
 
uint32 recruiterId
 
bool isRecruiter
 
LockedQueue< WorldPacket * > _recvQueue
 
uint32 m_currentVendorEntry
 
ObjectGuid m_currentBankerGUID
 
uint32 _offlineTime
 
bool _kicked
 
time_t _calendarEventCreationCooldown
 
std::atomic< uint32_addonMessageReceiveCount
 
CircularBuffer< std::pair< int64, uint32 > > _timeSyncClockDeltaQueue
 
int64 _timeSyncClockDelta
 
std::map< uint32, uint32_pendingTimeSyncRequests
 
uint32 _timeSyncNextCounter
 
uint32 _timeSyncTimer
 

Friends

class World
 

Detailed Description

Player session in the World.

Member Typedef Documentation

◆ AddonsList

typedef std::list<AddonInfo> WorldSession::AddonsList
private

Constructor & Destructor Documentation

◆ WorldSession() [1/2]

WorldSession::WorldSession ( uint32  id,
std::string &&  name,
std::shared_ptr< WorldSocket sock,
AccountTypes  sec,
uint8  expansion,
time_t  mute_time,
LocaleConstant  locale,
uint32  recruiter,
bool  isARecruiter,
bool  skipQueue,
uint32  TotalTime 
)

WorldSession constructor.

107 :
108 m_muteTime(mute_time),
109 m_timeOutTime(0),
112 AntiDOS(this),
113 m_GUIDLow(0),
114 _player(nullptr),
115 m_Socket(sock),
116 _security(sec),
117 _skipQueue(skipQueue),
118 _accountId(id),
119 _accountName(std::move(name)),
120 m_expansion(expansion),
121 m_total_time(TotalTime),
122 _logoutTime(0),
123 m_inQueue(false),
124 m_playerLoading(false),
125 m_playerLogout(false),
127 m_playerSave(false),
128 m_sessionDbcLocale(sWorld->GetDefaultDbcLocale()),
130 m_latency(0),
131 m_TutorialsChanged(false),
132 recruiterId(recruiter),
133 isRecruiter(isARecruiter),
140{
141 memset(m_Tutorials, 0, sizeof(m_Tutorials));
142
143 _offlineTime = 0;
144 _kicked = false;
145
147 _timeSyncTimer = 0;
148
149 if (sock)
150 {
151 m_Address = sock->GetRemoteIpAddress().to_string();
152 ResetTimeOutTime(false);
153 LoginDatabase.Execute("UPDATE account SET online = 1 WHERE id = {};", GetAccountId()); // One-time query
154 }
155}
DatabaseWorkerPool< LoginDatabaseConnection > LoginDatabase
Accessor to the realm/login database.
Definition: DatabaseEnv.cpp:22
#define sWorld
Definition: World.h:443
bool m_playerRecentlyLogout
Definition: WorldSession.h:1164
bool isRecruiter
Definition: WorldSession.h:1174
std::string m_Address
Definition: WorldSession.h:1146
uint32 _offlineTime
Definition: WorldSession.h:1178
bool m_playerSave
Definition: WorldSession.h:1165
LocaleConstant m_sessionDbLocaleIndex
Definition: WorldSession.h:1167
bool _skipQueue
Definition: WorldSession.h:1149
CircularBuffer< std::pair< int64, uint32 > > _timeSyncClockDeltaQueue
Definition: WorldSession.h:1186
bool m_TutorialsChanged
Definition: WorldSession.h:1171
time_t _logoutTime
Definition: WorldSession.h:1160
uint32 m_currentVendorEntry
Definition: WorldSession.h:1176
Milliseconds _lastAuctionListItemsMSTime
Definition: WorldSession.h:1062
int64 _timeSyncClockDelta
Definition: WorldSession.h:1187
std::atomic< uint32 > _addonMessageReceiveCount
Definition: WorldSession.h:1184
bool m_playerLoading
Definition: WorldSession.h:1162
std::shared_ptr< WorldSocket > m_Socket
Definition: WorldSession.h:1145
std::map< uint32, uint32 > _pendingTimeSyncRequests
Definition: WorldSession.h:1190
time_t _calendarEventCreationCooldown
Definition: WorldSession.h:1181
class WorldSession::DosProtection AntiDOS
std::atomic< time_t > m_timeOutTime
Definition: WorldSession.h:505
uint32 _timeSyncTimer
Definition: WorldSession.h:1192
uint32 m_total_time
Definition: WorldSession.h:1153
std::string _accountName
Definition: WorldSession.h:1151
uint32 _timeSyncNextCounter
Definition: WorldSession.h:1191
uint32 recruiterId
Definition: WorldSession.h:1173
bool m_playerLogout
Definition: WorldSession.h:1163
uint32 _accountId
Definition: WorldSession.h:1150
ObjectGuid::LowType m_GUIDLow
Definition: WorldSession.h:1143
uint32 GetAccountId() const
Definition: WorldSession.h:361
Milliseconds _lastAuctionListOwnerItemsMSTime
Definition: WorldSession.h:1063
Player * _player
Definition: WorldSession.h:1144
AccountTypes _security
Definition: WorldSession.h:1148
bool m_inQueue
Definition: WorldSession.h:1161
LocaleConstant m_sessionDbcLocale
Definition: WorldSession.h:1166
time_t m_muteTime
Definition: WorldSession.h:494
std::atomic< uint32 > m_latency
Definition: WorldSession.h:1168
void ResetTimeOutTime(bool onlyActive)
Definition: WorldSession.h:513
uint32 m_Tutorials[MAX_ACCOUNT_TUTORIAL_VALUES]
Definition: WorldSession.h:1170
uint8 m_expansion
Definition: WorldSession.h:1152
bool _kicked
Definition: WorldSession.h:1179

References _kicked, _offlineTime, _timeSyncNextCounter, _timeSyncTimer, GetAccountId(), LoginDatabase, m_Address, m_Tutorials, and ResetTimeOutTime().

◆ ~WorldSession()

WorldSession::~WorldSession ( )

WorldSession destructor.

  • unload player if not unloaded
  • If have unclosed socket, close it
  • empty incoming packet queue
159{
160 LoginDatabase.Execute("UPDATE account SET totaltime = {} WHERE id = {}", GetTotalTime(), GetAccountId());
161
163 if (_player)
164 LogoutPlayer(true);
165
167 if (m_Socket)
168 {
169 m_Socket->CloseSocket();
170 m_Socket = nullptr;
171 }
172
174 WorldPacket* packet = nullptr;
175 while (_recvQueue.next(packet))
176 delete packet;
177
178 LoginDatabase.Execute("UPDATE account SET online = 0 WHERE id = {};", GetAccountId()); // One-time query
179}
bool next(T &result)
Gets the next result in the queue, if any.
Definition: LockedQueue.h:63
Definition: WorldPacket.h:27
void LogoutPlayer(bool save)
Log the player out
Definition: WorldSession.cpp:573
uint32 GetTotalTime() const
Definition: WorldSession.h:376
LockedQueue< WorldPacket * > _recvQueue
Definition: WorldSession.h:1175

References _player, _recvQueue, GetAccountId(), GetTotalTime(), LoginDatabase, LogoutPlayer(), m_Socket, and LockedQueue< T, StorageType >::next().

◆ WorldSession() [2/2]

WorldSession::WorldSession ( WorldSession const &  right)
privatedelete

Member Function Documentation

◆ AddQueryHolderCallback()

SQLQueryHolderCallback & WorldSession::AddQueryHolderCallback ( SQLQueryHolderCallback &&  callback)
1283{
1284 return _queryHolderProcessor.AddCallback(std::move(callback));
1285}
T & AddCallback(T &&query)
Definition: AsyncCallbackProcessor.h:34
AsyncCallbackProcessor< SQLQueryHolderCallback > _queryHolderProcessor
Definition: WorldSession.h:1089

References _queryHolderProcessor, and AsyncCallbackProcessor< T >::AddCallback().

Referenced by HandlePlayerLoginOpcode(), InitializeSession(), and Pet::LoadPetFromDB().

◆ AddTransactionCallback()

TransactionCallback & WorldSession::AddTransactionCallback ( TransactionCallback &&  callback)
1278{
1279 return _transactionCallbacks.AddCallback(std::move(callback));
1280}
AsyncCallbackProcessor< TransactionCallback > _transactionCallbacks
Definition: WorldSession.h:1088

References _transactionCallbacks, and AsyncCallbackProcessor< T >::AddCallback().

◆ BuildPartyMemberStatsChangedPacket()

void WorldSession::BuildPartyMemberStatsChangedPacket ( Player player,
WorldPacket data 
)
768{
769 uint32 mask = player->GetGroupUpdateFlag();
770
771 if (mask == GROUP_UPDATE_FLAG_NONE)
772 return;
773
774 if (mask & GROUP_UPDATE_FLAG_POWER_TYPE) // if update power type, update current/max power also
776
777 if (mask & GROUP_UPDATE_FLAG_PET_POWER_TYPE) // same for pets
779
780 uint32 byteCount = 0;
781 for (int i = 1; i < GROUP_UPDATE_FLAGS_COUNT; ++i)
782 if (mask & (1 << i))
783 byteCount += GroupUpdateLength[i];
784
785 data->Initialize(SMSG_PARTY_MEMBER_STATS, 8 + 4 + byteCount);
786 *data << player->GetPackGUID();
787 *data << uint32(mask);
788
789 if (mask & GROUP_UPDATE_FLAG_STATUS)
790 {
791 uint16 playerStatus = MEMBER_STATUS_ONLINE;
792 if (player->IsPvP())
793 playerStatus |= MEMBER_STATUS_PVP;
794
795 if (!player->IsAlive())
796 {
798 playerStatus |= MEMBER_STATUS_GHOST;
799 else
800 playerStatus |= MEMBER_STATUS_DEAD;
801 }
802
803 if (player->IsFFAPvP())
804 playerStatus |= MEMBER_STATUS_PVP_FFA;
805
806 if (player->isAFK())
807 playerStatus |= MEMBER_STATUS_AFK;
808
809 if (player->isDND())
810 playerStatus |= MEMBER_STATUS_DND;
811
812 *data << uint16(playerStatus);
813 }
814
815 if (mask & GROUP_UPDATE_FLAG_CUR_HP)
816 *data << uint32(player->GetHealth());
817
818 if (mask & GROUP_UPDATE_FLAG_MAX_HP)
819 *data << uint32(player->GetMaxHealth());
820
821 Powers powerType = player->getPowerType();
823 *data << uint8(powerType);
824
826 *data << uint16(player->GetPower(powerType));
827
829 *data << uint16(player->GetMaxPower(powerType));
830
831 if (mask & GROUP_UPDATE_FLAG_LEVEL)
832 *data << uint16(player->GetLevel());
833
834 if (mask & GROUP_UPDATE_FLAG_ZONE)
835 *data << uint16(player->GetZoneId());
836
838 {
839 *data << uint16(player->GetPositionX());
840 *data << uint16(player->GetPositionY());
841 }
842
843 if (mask & GROUP_UPDATE_FLAG_AURAS)
844 {
845 uint64 auramask = player->GetAuraUpdateMaskForRaid();
846 *data << uint64(auramask);
847 for (uint32 i = 0; i < MAX_AURAS_GROUP_UPDATE; ++i)
848 {
849 if (auramask & (uint64(1) << i))
850 {
851 AuraApplication const* aurApp = player->GetVisibleAura(i);
852 *data << uint32(aurApp ? aurApp->GetBase()->GetId() : 0);
853 *data << uint8(1);
854 }
855 }
856 }
857
858 Pet* pet = player->GetPet();
860 {
861 if (pet)
862 *data << pet->GetGUID();
863 else
864 *data << (uint64) 0;
865 }
866
868 {
869 if (pet)
870 *data << pet->GetName();
871 else
872 *data << uint8(0);
873 }
874
876 {
877 if (pet)
878 *data << uint16(pet->GetDisplayId());
879 else
880 *data << uint16(0);
881 }
882
884 {
885 if (pet)
886 *data << uint32(pet->GetHealth());
887 else
888 *data << uint32(0);
889 }
890
892 {
893 if (pet)
894 *data << uint32(pet->GetMaxHealth());
895 else
896 *data << uint32(0);
897 }
898
900 {
901 if (pet)
902 *data << uint8(pet->getPowerType());
903 else
904 *data << uint8(0);
905 }
906
908 {
909 if (pet)
910 *data << uint16(pet->GetPower(pet->getPowerType()));
911 else
912 *data << uint16(0);
913 }
914
916 {
917 if (pet)
918 *data << uint16(pet->GetMaxPower(pet->getPowerType()));
919 else
920 *data << uint16(0);
921 }
922
924 {
925 if (pet)
926 {
927 uint64 auramask = pet->GetAuraUpdateMaskForRaid();
928 *data << uint64(auramask);
929 for (uint32 i = 0; i < MAX_AURAS_GROUP_UPDATE; ++i)
930 {
931 if (auramask & (uint64(1) << i))
932 {
933 AuraApplication const* aurApp = pet->GetVisibleAura(i);
934 *data << uint32(aurApp ? aurApp->GetBase()->GetId() : 0);
935 *data << uint8(aurApp ? aurApp->GetFlags() : 0);
936 }
937 }
938 }
939 else
940 *data << uint64(0);
941 }
942
944 {
945 if (Vehicle* veh = player->GetVehicle())
946 * data << uint32(veh->GetVehicleInfo()->m_seatID[player->m_movementInfo.transport.seat]);
947 else
948 *data << uint32(0);
949 }
950}
std::uint8_t uint8
Definition: Define.h:109
std::uint32_t uint32
Definition: Define.h:107
std::uint64_t uint64
Definition: Define.h:106
std::uint16_t uint16
Definition: Define.h:108
@ MEMBER_STATUS_AFK
Definition: Group.h:67
@ MEMBER_STATUS_PVP
Definition: Group.h:62
@ MEMBER_STATUS_ONLINE
Definition: Group.h:61
@ MEMBER_STATUS_DEAD
Definition: Group.h:63
@ MEMBER_STATUS_GHOST
Definition: Group.h:64
@ MEMBER_STATUS_DND
Definition: Group.h:68
@ MEMBER_STATUS_PVP_FFA
Definition: Group.h:65
static const uint8 GroupUpdateLength[GROUP_UPDATE_FLAGS_COUNT]
Definition: Group.h:140
@ GROUP_UPDATE_FLAG_CUR_HP
Definition: Group.h:101
@ GROUP_UPDATE_FLAG_PET_CUR_HP
Definition: Group.h:113
@ GROUP_UPDATE_FLAG_POWER_TYPE
Definition: Group.h:103
@ GROUP_UPDATE_FLAG_PET_CUR_POWER
Definition: Group.h:116
@ GROUP_UPDATE_FLAG_PET_MAX_POWER
Definition: Group.h:117
@ GROUP_UPDATE_FLAG_MAX_HP
Definition: Group.h:102
@ GROUP_UPDATE_FLAG_VEHICLE_SEAT
Definition: Group.h:119
@ GROUP_UPDATE_FLAG_STATUS
Definition: Group.h:100
@ GROUP_UPDATE_FLAG_PET_POWER_TYPE
Definition: Group.h:115
@ GROUP_UPDATE_FLAG_MAX_POWER
Definition: Group.h:105
@ GROUP_UPDATE_FLAG_ZONE
Definition: Group.h:107
@ GROUP_UPDATE_FLAG_NONE
Definition: Group.h:99
@ GROUP_UPDATE_FLAG_POSITION
Definition: Group.h:108
@ GROUP_UPDATE_FLAG_PET_MODEL_ID
Definition: Group.h:112
@ GROUP_UPDATE_FLAG_PET_NAME
Definition: Group.h:111
@ GROUP_UPDATE_FLAG_PET_AURAS
Definition: Group.h:118
@ GROUP_UPDATE_FLAG_AURAS
Definition: Group.h:109
@ GROUP_UPDATE_FLAG_LEVEL
Definition: Group.h:106
@ GROUP_UPDATE_FLAG_PET_GUID
Definition: Group.h:110
@ GROUP_UPDATE_FLAG_PET_MAX_HP
Definition: Group.h:114
@ GROUP_UPDATE_FLAG_CUR_POWER
Definition: Group.h:104
#define GROUP_UPDATE_FLAGS_COUNT
Definition: Group.h:138
@ PLAYER_FLAGS_GHOST
Definition: Player.h:478
#define MAX_AURAS_GROUP_UPDATE
Definition: SpellAuraDefines.h:22
Powers
Definition: SharedDefines.h:268
@ SMSG_PARTY_MEMBER_STATS
Definition: Opcodes.h:156
PackedGuid const & GetPackGUID() const
Definition: Object.h:111
static ObjectGuid GetGUID(Object const *o)
Definition: Object.h:109
struct MovementInfo::TransportInfo transport
int8 seat
Definition: Object.h:298
std::string const & GetName() const
Definition: Object.h:458
uint32 GetZoneId() const
Definition: Object.cpp:3146
MovementInfo m_movementInfo
Definition: Object.h:609
float GetPositionX() const
Definition: Position.h:117
float GetPositionY() const
Definition: Position.h:118
Definition: Pet.h:41
uint64 GetAuraUpdateMaskForRaid() const
Definition: Pet.h:136
uint64 GetAuraUpdateMaskForRaid() const
Definition: Player.h:2457
Pet * GetPet() const
Definition: Player.cpp:8906
bool IsFFAPvP()
Definition: Player.cpp:16224
bool isDND() const
Definition: Player.h:1135
uint32 GetGroupUpdateFlag() const
Definition: Player.h:2455
bool HasPlayerFlag(PlayerFlags flags) const
Definition: Player.h:1108
bool isAFK() const
Definition: Player.h:1134
bool IsPvP()
Definition: Player.cpp:16233
Vehicle * GetVehicle() const
Definition: Unit.h:1687
AuraApplication * GetVisibleAura(uint8 slot)
Definition: Unit.h:1505
uint32 GetMaxHealth() const
Definition: Unit.h:870
bool IsAlive() const
Definition: Unit.h:1216
uint32 GetDisplayId() const
Definition: Unit.h:1521
uint32 GetMaxPower(Powers power) const
Definition: Unit.h:892
uint32 GetHealth() const
Definition: Unit.h:869
Powers getPowerType() const
Definition: Unit.h:888
uint32 GetPower(Powers power) const
Definition: Unit.h:891
uint8 GetLevel() const
Definition: Unit.h:855
Definition: Vehicle.h:28
void Initialize(uint16 opcode, std::size_t newres=200)
Definition: WorldPacket.h:69
Definition: SpellAuras.h:37
uint8 GetFlags() const
Definition: SpellAuras.h:65
Aura * GetBase() const
Definition: SpellAuras.h:62
uint32 GetId() const
Definition: SpellAuras.cpp:466

References Pet::GetAuraUpdateMaskForRaid(), Player::GetAuraUpdateMaskForRaid(), AuraApplication::GetBase(), Unit::GetDisplayId(), AuraApplication::GetFlags(), Player::GetGroupUpdateFlag(), Object::GetGUID(), Unit::GetHealth(), Aura::GetId(), Unit::GetLevel(), Unit::GetMaxHealth(), Unit::GetMaxPower(), WorldObject::GetName(), Object::GetPackGUID(), Player::GetPet(), Position::GetPositionX(), Position::GetPositionY(), Unit::GetPower(), Unit::getPowerType(), Unit::GetVehicle(), Unit::GetVisibleAura(), WorldObject::GetZoneId(), GROUP_UPDATE_FLAG_AURAS, GROUP_UPDATE_FLAG_CUR_HP, GROUP_UPDATE_FLAG_CUR_POWER, GROUP_UPDATE_FLAG_LEVEL, GROUP_UPDATE_FLAG_MAX_HP, GROUP_UPDATE_FLAG_MAX_POWER, GROUP_UPDATE_FLAG_NONE, GROUP_UPDATE_FLAG_PET_AURAS, GROUP_UPDATE_FLAG_PET_CUR_HP, GROUP_UPDATE_FLAG_PET_CUR_POWER, GROUP_UPDATE_FLAG_PET_GUID, GROUP_UPDATE_FLAG_PET_MAX_HP, GROUP_UPDATE_FLAG_PET_MAX_POWER, GROUP_UPDATE_FLAG_PET_MODEL_ID, GROUP_UPDATE_FLAG_PET_NAME, GROUP_UPDATE_FLAG_PET_POWER_TYPE, GROUP_UPDATE_FLAG_POSITION, GROUP_UPDATE_FLAG_POWER_TYPE, GROUP_UPDATE_FLAG_STATUS, GROUP_UPDATE_FLAG_VEHICLE_SEAT, GROUP_UPDATE_FLAG_ZONE, GROUP_UPDATE_FLAGS_COUNT, GroupUpdateLength, Player::HasPlayerFlag(), WorldPacket::Initialize(), Player::isAFK(), Unit::IsAlive(), Player::isDND(), Player::IsFFAPvP(), Player::IsPvP(), WorldObject::m_movementInfo, MAX_AURAS_GROUP_UPDATE, MEMBER_STATUS_AFK, MEMBER_STATUS_DEAD, MEMBER_STATUS_DND, MEMBER_STATUS_GHOST, MEMBER_STATUS_ONLINE, MEMBER_STATUS_PVP, MEMBER_STATUS_PVP_FFA, PLAYER_FLAGS_GHOST, MovementInfo::TransportInfo::seat, SMSG_PARTY_MEMBER_STATS, and MovementInfo::transport.

Referenced by Group::UpdatePlayerOutOfRange().

◆ CanOpenMailBox()

bool WorldSession::CanOpenMailBox ( ObjectGuid  guid)
38{
39 if (guid == _player->GetGUID())
40 {
42 {
43 LOG_ERROR("network.opcode", "{} attempt open mailbox in cheating way.", _player->GetName());
44 return false;
45 }
46 }
47 else if (guid.IsGameObject())
48 {
50 return false;
51 }
52 else if (guid.IsAnyTypeCreature())
53 {
55 return false;
56 }
57 else
58 return false;
59
60 return true;
61}
@ SEC_MODERATOR
Definition: Common.h:58
#define LOG_ERROR(filterType__,...)
Definition: Log.h:156
@ UNIT_NPC_FLAG_MAILBOX
Definition: UnitDefines.h:320
@ GAMEOBJECT_TYPE_MAILBOX
Definition: SharedDefines.h:1579
bool IsGameObject() const
Definition: ObjectGuid.h:171
bool IsAnyTypeCreature() const
Definition: ObjectGuid.h:167
GameObject * GetGameObjectIfCanInteractWith(ObjectGuid guid, GameobjectTypes type) const
Definition: Player.cpp:2132
WorldSession * GetSession() const
Definition: Player.h:1980
Creature * GetNPCIfCanInteractWith(ObjectGuid guid, uint32 npcflagmask)
Definition: Player.cpp:2075
AccountTypes GetSecurity() const
Definition: WorldSession.h:359

References _player, GAMEOBJECT_TYPE_MAILBOX, Player::GetGameObjectIfCanInteractWith(), Object::GetGUID(), WorldObject::GetName(), Player::GetNPCIfCanInteractWith(), GetSecurity(), Player::GetSession(), ObjectGuid::IsAnyTypeCreature(), ObjectGuid::IsGameObject(), LOG_ERROR, SEC_MODERATOR, and UNIT_NPC_FLAG_MAILBOX.

Referenced by HandleGetMailList(), HandleMailCreateTextItem(), HandleMailDelete(), HandleMailMarkAsRead(), HandleMailReturnToSender(), HandleMailTakeItem(), HandleMailTakeMoney(), and HandleSendMail().

◆ CanSkipQueue()

bool WorldSession::CanSkipQueue ( ) const
inline
360{ return _skipQueue; }

References _skipQueue.

Referenced by World::AddSession_().

◆ CanUseBank()

bool WorldSession::CanUseBank ( ObjectGuid  bankerGUID = ObjectGuid::Empty) const
private
27{
28 // bankerGUID parameter is optional, set to 0 by default.
29 if (!bankerGUID)
30 bankerGUID = m_currentBankerGUID;
31
32 bool isUsingBankCommand = (bankerGUID == GetPlayer()->GetGUID() && bankerGUID == m_currentBankerGUID);
33
34 if (!isUsingBankCommand)
35 {
37 if (!creature)
38 return false;
39 }
40
41 return true;
42}
@ UNIT_NPC_FLAG_BANKER
Definition: UnitDefines.h:311
Definition: Creature.h:46
Player * GetPlayer() const
Definition: WorldSession.h:362
ObjectGuid m_currentBankerGUID
Definition: WorldSession.h:1177

References Object::GetGUID(), Player::GetNPCIfCanInteractWith(), GetPlayer(), m_currentBankerGUID, and UNIT_NPC_FLAG_BANKER.

Referenced by HandleAutoBankItemOpcode(), HandleAutoStoreBankItemOpcode(), HandleBuyBankSlotOpcode(), HandleSwapInvItemOpcode(), and HandleSwapItem().

◆ CheckStableMaster()

bool WorldSession::CheckStableMaster ( ObjectGuid  guid)
652{
653 // spell case or GM
654 if (guid == GetPlayer()->GetGUID())
655 {
656 if (!GetPlayer()->IsGameMaster() && !GetPlayer()->HasAuraType(SPELL_AURA_OPEN_STABLE))
657 {
658 LOG_DEBUG("network.opcode", "Player ({}) attempt open stable in cheating way.", guid.ToString());
659 return false;
660 }
661 }
662 // stable master case
663 else
664 {
665 if (!GetPlayer()->GetNPCIfCanInteractWith(guid, UNIT_NPC_FLAG_STABLEMASTER))
666 {
667 LOG_DEBUG("network.opcode", "Stablemaster ({}) not found or you can't interact with him.", guid.ToString());
668 return false;
669 }
670 }
671 return true;
672}
#define LOG_DEBUG(filterType__,...)
Definition: Log.h:168
@ UNIT_NPC_FLAG_STABLEMASTER
Definition: UnitDefines.h:316
@ SPELL_AURA_OPEN_STABLE
Definition: SpellAuraDefines.h:355
std::string ToString() const
Definition: ObjectGuid.cpp:47

References GetPlayer(), LOG_DEBUG, SPELL_AURA_OPEN_STABLE, ObjectGuid::ToString(), and UNIT_NPC_FLAG_STABLEMASTER.

Referenced by HandleBuyStableSlot(), HandleListStabledPetsOpcode(), HandleStablePet(), HandleStableSwapPet(), and HandleUnstablePet().

◆ ComputeNewClockDelta()

void WorldSession::ComputeNewClockDelta ( )
private
919{
920 // implementation of the technique described here: https://web.archive.org/web/20180430214420/http://www.mine-control.com/zack/timesync/timesync.html
921 // to reduce the skew induced by dropped TCP packets that get resent.
922
923 std::vector<uint32> latencies;
924 std::vector<int64> clockDeltasAfterFiltering;
925
926 for (auto& pair : _timeSyncClockDeltaQueue.content())
927 latencies.push_back(pair.second);
928
929 uint32 latencyMedian = median(latencies);
930 uint32 latencyStandardDeviation = standard_deviation(latencies);
931
932 uint32 sampleSizeAfterFiltering = 0;
933 for (auto& pair : _timeSyncClockDeltaQueue.content())
934 {
935 if (pair.second <= latencyMedian + latencyStandardDeviation) {
936 clockDeltasAfterFiltering.push_back(pair.first);
937 sampleSizeAfterFiltering++;
938 }
939 }
940
941 if (sampleSizeAfterFiltering != 0)
942 {
943 int64 meanClockDelta = static_cast<int64>(mean(clockDeltasAfterFiltering));
944 if (std::abs(meanClockDelta - _timeSyncClockDelta) > 25)
945 _timeSyncClockDelta = meanClockDelta;
946 }
947 else if (_timeSyncClockDelta == 0)
948 {
949 std::pair<int64, uint32> back = _timeSyncClockDeltaQueue.peak_back();
950 _timeSyncClockDelta = back.first;
951 }
952}
T median(std::vector< T > a)
Definition: MathUtil.h:59
T standard_deviation(Container &&c)
Definition: MathUtil.h:28
T mean(Container &&c)
Definition: MathUtil.h:49
std::int64_t int64
Definition: Define.h:102
std::vector< T > content()
Definition: CircularBuffer.h:81
T peak_back()
Definition: CircularBuffer.h:88

References _timeSyncClockDelta, _timeSyncClockDeltaQueue, CircularBuffer< T >::content(), mean(), median(), CircularBuffer< T >::peak_back(), and standard_deviation().

Referenced by HandleTimeSyncResp().

◆ DisallowHyperlinksAndMaybeKick()

bool WorldSession::DisallowHyperlinksAndMaybeKick ( std::string_view  str)
780{
781 if (str.find('|') == std::string_view::npos)
782 return true;
783
784 LOG_ERROR("network", "Player {} {} sent a message which illegally contained a hyperlink:\n%.*s", GetPlayer()->GetName(),
785 GetPlayer()->GetGUID().ToString(), STRING_VIEW_FMT_ARG(str));
786
788 KickPlayer("WorldSession::DisallowHyperlinksAndMaybeKick Illegal chat link");
789
790 return false;
791}
#define STRING_VIEW_FMT_ARG(str)
Definition: Define.h:100
@ CONFIG_CHAT_STRICT_LINK_CHECKING_KICK
Definition: IWorld.h:289
std::string ToString(Type &&val, Params &&... params)
Definition: StringConvert.h:250
bool GetName(uint32 accountId, std::string &name)
Definition: AccountMgr.cpp:257
void KickPlayer(bool setKicked=true)
Definition: WorldSession.h:400

References CONFIG_CHAT_STRICT_LINK_CHECKING_KICK, GetPlayer(), KickPlayer(), LOG_ERROR, STRING_VIEW_FMT_ARG, and sWorld.

Referenced by HandleJoinChannel().

◆ DoLootRelease()

void WorldSession::DoLootRelease ( ObjectGuid  lguid)
271{
272 Player* player = GetPlayer();
273 Loot* loot;
274
276 player->SendLootRelease(lguid);
277
279
280 if (!player->IsInWorld())
281 return;
282
283 if (lguid.IsGameObject())
284 {
285 GameObject* go = GetPlayer()->GetMap()->GetGameObject(lguid);
286
287 // not check distance for GO in case owned GO (fishing bobber case, for example) or Fishing hole GO
288 if (!go || ((go->GetOwnerGUID() != _player->GetGUID() && go->GetGoType() != GAMEOBJECT_TYPE_FISHINGHOLE) && !go->IsWithinDistInMap(_player)))
289 {
290 return;
291 }
292
293 loot = &go->loot;
294
295 if (go->GetGoType() == GAMEOBJECT_TYPE_DOOR)
296 {
297 // locked doors are opened with spelleffect openlock, prevent remove its as looted
298 go->UseDoorOrButton();
299 }
300 else if (loot->isLooted() || go->GetGoType() == GAMEOBJECT_TYPE_FISHINGNODE)
301 {
303 {
304 // The fishing hole used once more
305 go->AddUse(); // if the max usage is reached, will be despawned in next tick
306 if (go->GetUseCount() >= go->GetGOValue()->FishingHole.MaxOpens)
308 else
310 }
311 else
312 {
314
315 // Xinef: moved event execution to loot release (after everything is looted)
316 // Xinef: 99% sure that this worked like this on blizz
317 // Xinef: prevents exploits with just opening GO and spawning bilions of npcs, which can crash core if you know what you're doin ;)
319 {
320 LOG_DEBUG("spells.aura", "Chest ScriptStart id {} for GO {}", go->GetGOInfo()->chest.eventId, go->GetSpawnId());
321 player->GetMap()->ScriptsStart(sEventScripts, go->GetGOInfo()->chest.eventId, player, go);
322 }
323 }
324
325 loot->clear();
326 }
327 else
328 {
329 // not fully looted object
330 go->SetLootState(GO_ACTIVATED, player);
331
332 // if the round robin player release, reset it.
333 if (player->GetGUID() == loot->roundRobinPlayer)
334 loot->roundRobinPlayer.Clear();
335 }
336 }
337 else if (lguid.IsCorpse()) // ONLY remove insignia at BG
338 {
339 Corpse* corpse = ObjectAccessor::GetCorpse(*player, lguid);
340 if (!corpse || !corpse->IsWithinDistInMap(_player, INTERACTION_DISTANCE))
341 return;
342
343 loot = &corpse->loot;
344
345 // Xinef: Buggs client? (Opening loot after closing)
346 //if (loot->isLooted())
347 {
348 loot->clear();
350 }
351 }
352 else if (lguid.IsItem())
353 {
354 Item* pItem = player->GetItemByGuid(lguid);
355 if (!pItem)
356 return;
357
358 loot = &pItem->loot;
359 ItemTemplate const* proto = pItem->GetTemplate();
360
361 // destroy only 5 items from stack in case prospecting and milling
363 {
364 pItem->m_lootGenerated = false;
365 pItem->loot.clear();
366
367 uint32 count = pItem->GetCount();
368
369 // >=5 checked in spell code, but will work for cheating cases also with removing from another stacks.
370 if (count > 5)
371 count = 5;
372
373 player->DestroyItemCount(pItem, count, true);
374 }
375 else if (pItem->loot.isLooted() || !proto->HasFlag(ITEM_FLAG_HAS_LOOT))
376 {
377 player->DestroyItem(pItem->GetBagSlot(), pItem->GetSlot(), true);
378 return;
379 }
380 }
381 else
382 {
383 Creature* creature = GetPlayer()->GetMap()->GetCreature(lguid);
384
385 bool lootAllowed = creature && creature->IsAlive() == (player->IsClass(CLASS_ROGUE, CLASS_CONTEXT_ABILITY) && creature->loot.loot_type == LOOT_PICKPOCKETING);
386 if (!lootAllowed || !creature->IsWithinDistInMap(_player, INTERACTION_DISTANCE))
387 return;
388
389 loot = &creature->loot;
390 if (loot->isLooted())
391 {
392 // skip pickpocketing loot for speed, skinning timer reduction is no-op in fact
393 if (!creature->IsAlive())
394 creature->AllLootRemovedFromCorpse();
395
397 loot->clear();
398 }
399 else
400 {
401 // if the round robin player release, reset it.
402 if (player->GetGUID() == loot->roundRobinPlayer)
403 {
404 loot->roundRobinPlayer.Clear();
405
406 if (Group* group = player->GetGroup())
407 group->SendLooter(creature, nullptr);
408 }
409 // force dynflag update to update looter and lootable info
411 }
412 }
413
414 //Player is not looking at loot list, he doesn't need to see updates on the loot list
415 if (!lguid.IsItem())
416 {
417 loot->RemoveLooter(player->GetGUID());
418 }
419}
ScriptMapMap sEventScripts
Definition: ObjectMgr.cpp:58
@ LOOT_PICKPOCKETING
Definition: LootMgr.h:82
@ CLASS_CONTEXT_ABILITY
Definition: UnitDefines.h:213
@ UNIT_FLAG_LOOTING
Definition: UnitDefines.h:239
@ CORPSE_FIELD_DYNAMIC_FLAGS
Definition: UpdateFields.h:428
@ UNIT_DYNAMIC_FLAGS
Definition: UpdateFields.h:136
#define INTERACTION_DISTANCE
Definition: ObjectDefines.h:24
@ GO_ACTIVATED
Definition: GameObject.h:113
@ GO_READY
Definition: GameObject.h:112
@ GO_JUST_DEACTIVATED
Definition: GameObject.h:114
@ ITEM_FLAG_IS_MILLABLE
Definition: ItemTemplate.h:176
@ ITEM_FLAG_IS_PROSPECTABLE
Definition: ItemTemplate.h:165
@ ITEM_FLAG_HAS_LOOT
Definition: ItemTemplate.h:149
@ GAMEOBJECT_TYPE_CHEST
Definition: SharedDefines.h:1563
@ GAMEOBJECT_TYPE_FISHINGHOLE
Definition: SharedDefines.h:1585
@ GAMEOBJECT_TYPE_FISHINGNODE
Definition: SharedDefines.h:1577
@ GAMEOBJECT_TYPE_DOOR
Definition: SharedDefines.h:1560
@ CORPSE_DYNFLAG_LOOTABLE
Definition: SharedDefines.h:3133
@ UNIT_DYNFLAG_LOOTABLE
Definition: SharedDefines.h:3121
@ CLASS_ROGUE
Definition: SharedDefines.h:144
Corpse * GetCorpse(WorldObject const &u, ObjectGuid const guid)
Definition: ObjectAccessor.cpp:179
Definition: Corpse.h:49
Loot loot
Definition: Corpse.h:77
Loot loot
Definition: Creature.h:229
void AllLootRemovedFromCorpse()
Definition: Creature.cpp:2987
uint32 MaxOpens
Definition: GameObject.h:61
struct GameObjectValue::@224 FishingHole
Definition: GameObject.h:121
bool IsWithinDistInMap(Player const *player) const
Definition: GameObject.cpp:3003
Loot loot
Definition: GameObject.h:248
void UseDoorOrButton(uint32 time_to_restore=0, bool alternative=false, Unit *user=nullptr)
Definition: GameObject.cpp:1429
GameObjectTemplate const * GetGOInfo() const
Definition: GameObject.h:137
void AddUse()
Definition: GameObject.h:240
GameObjectValue const * GetGOValue() const
Definition: GameObject.h:140
void SetLootState(LootState s, Unit *unit=nullptr)
Definition: GameObject.cpp:2442
ObjectGuid GetOwnerGUID() const
Definition: GameObject.h:174
GameobjectTypes GetGoType() const
Definition: GameObject.h:204
ObjectGuid::LowType GetSpawnId() const
Definition: GameObject.h:145
uint32 GetUseCount() const
Definition: GameObject.h:242
struct GameObjectTemplate::@227::@232 chest
uint32 eventId
Definition: GameObjectData.h:89
Definition: Item.h:220
uint8 GetSlot() const
Definition: Item.h:281
ItemTemplate const * GetTemplate() const
Definition: Item.cpp:545
bool m_lootGenerated
Definition: Item.h:321
uint32 GetCount() const
Definition: Item.h:272
Loot loot
Definition: Item.h:320
uint8 GetBagSlot() const
Definition: Item.cpp:785
Definition: ItemTemplate.h:619
bool HasFlag(ItemFlags flag) const
Definition: ItemTemplate.h:827
ItemFlags Flags
Definition: ItemTemplate.h:627
virtual void RemoveDynamicFlag(uint32 flag)
Definition: Object.h:121
bool IsInWorld() const
Definition: Object.h:104
void RemoveFlag(uint16 index, uint32 oldFlag)
Definition: Object.cpp:860
void ForceValuesUpdateAtIndex(uint32)
Definition: Object.cpp:2067
Map * GetMap() const
Definition: Object.h:531
bool IsWithinDistInMap(WorldObject const *obj, float dist2compare, bool is3D=true, bool useBoundingRadius=true) const
Definition: Object.cpp:1321
static ObjectGuid const Empty
Definition: ObjectGuid.h:120
bool IsCorpse() const
Definition: ObjectGuid.h:173
bool IsItem() const
Definition: ObjectGuid.h:170
void Clear()
Definition: ObjectGuid.h:138
Definition: Player.h:1064
void SendLootRelease(ObjectGuid guid)
Definition: Player.cpp:7766
void SetLootGUID(ObjectGuid guid)
Definition: Player.h:1976
void DestroyItem(uint8 bag, uint8 slot, bool update)
Definition: PlayerStorage.cpp:3025
bool IsClass(Classes playerClass, ClassContext context=CLASS_CONTEXT_NONE) const override
Definition: Player.cpp:1280
Group * GetGroup()
Definition: Player.h:2450
void DestroyItemCount(uint32 item, uint32 count, bool update, bool unequip_check=false)
Definition: PlayerStorage.cpp:3123
Item * GetItemByGuid(ObjectGuid guid) const
Definition: PlayerStorage.cpp:409
void RemoveUnitFlag(UnitFlags flags)
UnitFlags available in UnitDefines.h.
Definition: Unit.h:684
Definition: Group.h:169
Definition: LootMgr.h:313
bool isLooted() const
Definition: LootMgr.h:368
void clear()
Definition: LootMgr.h:343
ObjectGuid roundRobinPlayer
Definition: LootMgr.h:324
void RemoveLooter(ObjectGuid GUID)
Definition: LootMgr.h:374
LootType loot_type
Definition: LootMgr.h:326
void ScriptsStart(std::map< uint32, std::multimap< uint32, ScriptInfo > > const &scripts, uint32 id, Object *source, Object *target)
Put scripts in the execution queue.
Definition: MapScripts.cpp:33
GameObject * GetGameObject(ObjectGuid const guid)
Definition: Map.cpp:3319
Creature * GetCreature(ObjectGuid const guid)
Definition: Map.cpp:3314

References _player, GameObject::AddUse(), Creature::AllLootRemovedFromCorpse(), GameObjectTemplate::chest, CLASS_CONTEXT_ABILITY, CLASS_ROGUE, ObjectGuid::Clear(), Loot::clear(), CORPSE_DYNFLAG_LOOTABLE, CORPSE_FIELD_DYNAMIC_FLAGS, Player::DestroyItem(), Player::DestroyItemCount(), ObjectGuid::Empty, GameObjectTemplate::eventId, GameObjectValue::FishingHole, ItemTemplate::Flags, Object::ForceValuesUpdateAtIndex(), GAMEOBJECT_TYPE_CHEST, GAMEOBJECT_TYPE_DOOR, GAMEOBJECT_TYPE_FISHINGHOLE, GAMEOBJECT_TYPE_FISHINGNODE, Item::GetBagSlot(), ObjectAccessor::GetCorpse(), Item::GetCount(), Map::GetCreature(), Map::GetGameObject(), GameObject::GetGOInfo(), GameObject::GetGoType(), GameObject::GetGOValue(), Player::GetGroup(), Object::GetGUID(), Player::GetItemByGuid(), WorldObject::GetMap(), GameObject::GetOwnerGUID(), GetPlayer(), Item::GetSlot(), GameObject::GetSpawnId(), Item::GetTemplate(), GameObject::GetUseCount(), GO_ACTIVATED, GO_JUST_DEACTIVATED, GO_READY, ItemTemplate::HasFlag(), INTERACTION_DISTANCE, Unit::IsAlive(), Player::IsClass(), ObjectGuid::IsCorpse(), ObjectGuid::IsGameObject(), Object::IsInWorld(), ObjectGuid::IsItem(), Loot::isLooted(), GameObject::IsWithinDistInMap(), WorldObject::IsWithinDistInMap(), ITEM_FLAG_HAS_LOOT, ITEM_FLAG_IS_MILLABLE, ITEM_FLAG_IS_PROSPECTABLE, LOG_DEBUG, Corpse::loot, Creature::loot, GameObject::loot, Item::loot, LOOT_PICKPOCKETING, Loot::loot_type, Item::m_lootGenerated, GameObjectValue::MaxOpens, Object::RemoveDynamicFlag(), Object::RemoveFlag(), Loot::RemoveLooter(), Unit::RemoveUnitFlag(), Loot::roundRobinPlayer, Map::ScriptsStart(), Player::SendLootRelease(), Player::SetLootGUID(), GameObject::SetLootState(), sEventScripts, UNIT_DYNAMIC_FLAGS, UNIT_DYNFLAG_LOOTABLE, UNIT_FLAG_LOOTING, and GameObject::UseDoorOrButton().

Referenced by HandleAutostoreLootItemOpcode(), HandleLogoutRequestOpcode(), HandleLootMoneyOpcode(), HandleLootReleaseOpcode(), LogoutPlayer(), Player::RemoveFromWorld(), Player::SendLoot(), and Player::SwapItem().

◆ Expansion()

◆ GetAccountData()

AccountData * WorldSession::GetAccountData ( AccountDataType  type)
inline
450{ return &m_accountData[type]; }
AccountData m_accountData[NUM_ACCOUNT_DATA_TYPES]
Definition: WorldSession.h:1169

References m_accountData.

Referenced by HandleRequestAccountData(), and SendAccountDataTimes().

◆ GetAccountId()

uint32 WorldSession::GetAccountId ( ) const
inline
361{ return _accountId; }

References _accountId.

Referenced by World::AddSession_(), Warden::ApplyPenalty(), CharacterActionIpLogger::CharacterIPLogAction(), Spell::CheckCast(), Spell::CheckEffectTarget(), WorldSession::DosProtection::EvaluateOpcode(), GetPlayerInfo(), Player::GetsRecruitAFriendBonus(), HandleAcceptGrantLevel(), HandleAcceptTradeOpcode(), account_commandscript::HandleAccount2FARemoveCommand(), account_commandscript::HandleAccount2FASetupCommand(), account_commandscript::HandleAccountAddonCommand(), account_commandscript::HandleAccountCreateCommand(), account_commandscript::HandleAccountLockCountryCommand(), account_commandscript::HandleAccountLockIpCommand(), account_commandscript::HandleAccountPasswordCommand(), account_commandscript::HandleAccountSetAddonCommand(), account_commandscript::HandleAccountSetGmLevelCommand(), HandleAuctionPlaceBid(), HandleCharCreateOpcode(), HandleCharCustomize(), HandleCharCustomizeCallback(), HandleCharDeleteOpcode(), HandleCharEnum(), HandleCharEnumOpcode(), HandleCharFactionOrRaceChange(), HandleCharFactionOrRaceChangeCallback(), HandleCharRenameCallBack(), HandleCharRenameOpcode(), WardenWin::HandleData(), HandleDismissCritter(), HandleForceSpeedChangeAck(), HandleGrantLevel(), HandleMailReturnToSender(), HandleMailTakeItem(), Guild::HandleMemberDepositMoney(), Guild::HandleMemberWithdrawMoney(), misc_commandscript::HandleMuteCommand(), HandlePetitionSignOpcode(), misc_commandscript::HandlePInfoCommand(), HandlePlayerLoginFromDB(), HandlePlayerLoginOpcode(), HandleSendMail(), misc_commandscript::HandleUnmuteCommand(), HandleWhoisOpcode(), World::HasRecentlyDisconnected(), WardenMac::Init(), WardenWin::Init(), InitializeSession(), BattlegroundQueue::InviteGroupToBG(), Channel::JoinChannel(), Channel::KickOrBan(), KickPlayer(), Player::LoadFromDB(), LogCommandUsage(), LogoutPlayer(), go_ulduar_pure_saronite_deposit::OnGossipHello(), SaveTutorialsData(), AuctionHouseMgr::SendAuctionWonMail(), SetAccountData(), Channel::SetMode(), Channel::SetOwner(), Guild::Member::SetStats(), Channel::UnBan(), Update(), World::UpdateSessions(), WorldSession(), and ~WorldSession().

◆ GetAcoreString()

char const * WorldSession::GetAcoreString ( uint32  entry) const

◆ GetCalendarEventCreationCooldown()

time_t WorldSession::GetCalendarEventCreationCooldown ( ) const
inline

◆ GetCurrentVendor()

◆ GetGuidLow()

ObjectGuid::LowType WorldSession::GetGuidLow ( ) const

Get player guid if available. Use for logging purposes only.

209{
210 return GetPlayer() ? GetPlayer()->GetGUID().GetCounter() : 0;
211}
LowType GetCounter() const
Definition: ObjectGuid.h:145

References ObjectGuid::GetCounter(), Object::GetGUID(), and GetPlayer().

◆ GetLatency()

◆ GetModuleString()

std::string const * WorldSession::GetModuleString ( std::string  module,
uint32  id 
) const
799{
800 return sObjectMgr->GetModuleString(module, id, GetSessionDbLocaleIndex());
801}

References GetSessionDbLocaleIndex(), and sObjectMgr.

Referenced by ChatHandler::GetModuleString().

◆ GetOfflineTime()

uint32 WorldSession::GetOfflineTime ( ) const
inline
1068{ return _offlineTime; }

References _offlineTime.

Referenced by World::UpdateSessions().

◆ GetPlayer()

Player * WorldSession::GetPlayer ( ) const
inline
362{ return _player; }

References _player.

Referenced by Guild::_SendBankContent(), Guild::_SendBankList(), Warden::ApplyPenalty(), Guild::BroadcastToGuild(), CanUseBank(), CheckStableMaster(), DisallowHyperlinksAndMaybeKick(), DoLootRelease(), go_commandscript::DoTeleport(), ChatHandler::GetCreatureFromPlayerMapByDbGuid(), GetGuidLow(), ChatHandler::GetNearbyGameObject(), ChatHandler::GetObjectFromPlayerMapByDbGuid(), ChatHandler::GetPlayer(), ChatHandler::GetPlayerGroupAndGUIDByName(), ChatHandler::getSelectedCreature(), ChatHandler::getSelectedObject(), ChatHandler::getSelectedPlayer(), ChatHandler::getSelectedPlayerOrSelf(), ChatHandler::getSelectedUnit(), Guild::HandleAcceptMember(), account_commandscript::HandleAccountCreateCommand(), HandleActivateTaxiExpressOpcode(), HandleActivateTaxiOpcode(), HandleAddFriendOpcode(), HandleAddIgnoreOpcode(), misc_commandscript::HandleAddItemCommand(), misc_commandscript::HandleAddItemSetCommand(), Guild::HandleAddNewRank(), misc_commandscript::HandleAppearCommand(), HandleAreaSpiritHealerQueryOpcode(), HandleAreaSpiritHealerQueueOpcode(), HandleAreaTriggerOpcode(), HandleArenaTeamInviteOpcode(), HandleAttackStopOpcode(), HandleAuctionHelloOpcode(), HandleAuctionListBidderItems(), HandleAuctionListOwnerItemsEvent(), HandleAuctionPlaceBid(), HandleAuctionRemoveItem(), HandleAuctionSellItem(), HandleAutostoreLootItemOpcode(), bg_commandscript::HandleBagsClearCommand(), HandleBankerActivateOpcode(), HandleBattlemasterHelloOpcode(), HandleBattlemasterJoinArena(), HandleBattlemasterJoinOpcode(), HandleBinderActivateOpcode(), misc_commandscript::HandleBindSightCommand(), HandleBuybackItem(), Guild::HandleBuyBankTab(), HandleBuyItemInSlotOpcode(), HandleBuyItemOpcode(), HandleBuyStableSlot(), HandleCancelTempEnchantmentOpcode(), cast_commandscript::HandleCastBackCommand(), cast_commandscript::HandleCastCommand(), cast_commandscript::HandleCastDistCommand(), cheat_commandscript::HandleCasttimeCheatCommand(), HandleChangeSeatsOnControlledVehicle(), misc_commandscript::HandleChangeWeather(), HandleChannelAnnouncements(), HandleChannelBan(), HandleChannelInvite(), HandleChannelKick(), HandleChannelList(), HandleChannelModerateOpcode(), HandleChannelModerator(), HandleChannelMute(), HandleChannelOwner(), HandleChannelPassword(), HandleChannelSetOwner(), HandleChannelUnban(), HandleChannelUnmoderator(), HandleChannelUnmute(), HandleCharacterAuraFrozen(), character_commandscript::HandleCharacterCheckBankCommand(), character_commandscript::HandleCharacterLevelCommand(), HandleChatIgnoredOpcode(), cheat_commandscript::HandleCheatStatusCommand(), HandleClearChannelWatch(), misc_commandscript::HandleComeToMeCommand(), misc_commandscript::HandleCommentatorCommand(), HandleCompleteCinematic(), cheat_commandscript::HandleCoolDownCheatCommand(), misc_commandscript::HandleCooldownCommand(), HandleCorpseQueryOpcode(), misc_commandscript::HandleDamageCommand(), debug_commandscript::HandleDebugAreaTriggersCommand(), debug_commandscript::HandleDebugHostileRefListCommand(), debug_commandscript::HandleDebugLoSCommand(), debug_commandscript::HandleDebugSendOpcodeCommand(), debug_commandscript::HandleDebugSpawnVehicleCommand(), debug_commandscript::HandleDebugUnitStateCommand(), HandleDelFriendOpcode(), HandleDelIgnoreOpcode(), misc_commandscript::HandleDevCommand(), misc_commandscript::HandleDieCommand(), Guild::HandleDisband(), HandleDismissCritter(), misc_commandscript::HandleDismountCommand(), HandleDuelAcceptedOpcode(), HandleDuelCancelledOpcode(), HandleEjectPassenger(), HandleEmoteOpcode(), cheat_commandscript::HandleExploreCheatCommand(), HandleFarSightOpcode(), gobject_commandscript::HandleGameObjectActivateCommand(), gobject_commandscript::HandleGameObjectAddCommand(), gobject_commandscript::HandleGameObjectAddTempCommand(), gobject_commandscript::HandleGameObjectDeleteCommand(), gobject_commandscript::HandleGameObjectMoveCommand(), gobject_commandscript::HandleGameObjectNearCommand(), HandleGameobjectReportUse(), gobject_commandscript::HandleGameObjectTargetCommand(), gobject_commandscript::HandleGameObjectTurnCommand(), HandleGameObjectUseOpcode(), HandleGetChannelMemberCount(), misc_commandscript::HandleGetDistanceCommand(), gm_commandscript::HandleGMFlyCommand(), gm_commandscript::HandleGMListIngameCommand(), HandleGMResponseResolve(), HandleGMSurveySubmit(), ticket_commandscript::HandleGMTicketAssignToCommand(), ticket_commandscript::HandleGMTicketCloseByIdCommand(), ticket_commandscript::HandleGMTicketCommentCommand(), ticket_commandscript::HandleGMTicketCompleteCommand(), HandleGMTicketCreateOpcode(), ticket_commandscript::HandleGMTicketDeleteByIdCommand(), HandleGMTicketDeleteOpcode(), HandleGMTicketGetTicketOpcode(), ticket_commandscript::HandleGMTicketResponseDeleteCommand(), ticket_commandscript::HandleGMTicketUnAssignCommand(), HandleGMTicketUpdateOpcode(), gm_commandscript::HandleGMVisibleCommand(), cheat_commandscript::HandleGodModeCheatCommand(), go_commandscript::HandleGoGraveyardCommand(), go_commandscript::HandleGoGridCommand(), HandleGossipHelloOpcode(), HandleGossipSelectOptionOpcode(), go_commandscript::HandleGoTicketCommand(), go_commandscript::HandleGoXYZCommand(), go_commandscript::HandleGoZoneXYCommand(), misc_commandscript::HandleGPSCommand(), HandleGroupAcceptOpcode(), HandleGroupAssistantLeaderOpcode(), HandleGroupChangeSubGroupOpcode(), HandleGroupDeclineOpcode(), HandleGroupDisbandOpcode(), HandleGroupInviteOpcode(), HandleGroupRaidConvertOpcode(), HandleGroupSetLeaderOpcode(), misc_commandscript::HandleGroupSummonCommand(), HandleGroupSwapSubGroupOpcode(), HandleGroupUninviteGuidOpcode(), HandleGroupUninviteOpcode(), misc_commandscript::HandleGUIDCommand(), HandleGuildAcceptOpcode(), HandleGuildAddRankOpcode(), HandleGuildBankBuyTab(), HandleGuildBankDepositMoney(), HandleGuildBankerActivate(), HandleGuildBankLogQuery(), HandleGuildBankMoneyWithdrawn(), HandleGuildBankQueryTab(), HandleGuildBankSwapItems(), HandleGuildBankUpdateTab(), HandleGuildBankWithdrawMoney(), HandleGuildChangeInfoTextOpcode(), HandleGuildDeclineOpcode(), HandleGuildDelRankOpcode(), HandleGuildDemoteOpcode(), HandleGuildDisbandOpcode(), HandleGuildEventLogQueryOpcode(), HandleGuildInfoOpcode(), HandleGuildInviteOpcode(), HandleGuildLeaderOpcode(), HandleGuildLeaveOpcode(), HandleGuildMOTDOpcode(), HandleGuildPermissions(), HandleGuildPromoteOpcode(), HandleGuildRankOpcode(), HandleGuildRemoveOpcode(), HandleGuildRosterOpcode(), HandleGuildSetOfficerNoteOpcode(), HandleGuildSetPublicNoteOpcode(), honor_commandscript::HandleHonorAddKillCommand(), HandleInitiateTradeOpcode(), HandleInspectArenaTeamsOpcode(), HandleInspectHonorStatsOpcode(), HandleInspectOpcode(), instance_commandscript::HandleInstanceListBindsCommand(), instance_commandscript::HandleInstanceSaveDataCommand(), instance_commandscript::HandleInstanceUnbindCommand(), Guild::HandleInviteMember(), item_commandscript::HandleItemMoveCommand(), HandleItemRefund(), HandleItemRefundInfoRequest(), HandleJoinChannel(), misc_commandscript::HandleKickPlayerCommand(), learn_commandscript::HandleLearnAllCraftsCommand(), learn_commandscript::HandleLearnAllGMCommand(), learn_commandscript::HandleLearnAllMyPetTalentsCommand(), learn_commandscript::HandleLearnAllMySpellsCommand(), learn_commandscript::HandleLearnAllMyTalentsCommand(), HandleLeaveChannel(), Guild::HandleLeaveMember(), character_commandscript::HandleLevelUpCommand(), HandleLfgGetStatus(), HandleLfgJoinOpcode(), HandleLfgLeaveOpcode(), HandleLfgPartyLockInfoRequestOpcode(), HandleLfgPlayerLockInfoRequestOpcode(), HandleLfgProposalResultOpcode(), HandleLfgSetBootVoteOpcode(), HandleLfgSetCommentOpcode(), HandleLfgSetRolesOpcode(), HandleLfgTeleportOpcode(), HandleLfrSearchJoinOpcode(), HandleLfrSearchLeaveOpcode(), misc_commandscript::HandleLinkGraveCommand(), list_commandscript::HandleListCreatureCommand(), HandleListInventoryOpcode(), list_commandscript::HandleListObjectCommand(), HandleListStabledPetsOpcode(), HandleLoadActionsSwitchSpec(), HandleLogoutCancelOpcode(), HandleLogoutRequestOpcode(), lookup_commandscript::HandleLookupPlayerIpCommand(), HandleLootMasterGiveOpcode(), HandleLootMethodOpcode(), HandleLootMoneyOpcode(), HandleLootOpcode(), HandleLootReleaseOpcode(), HandleLootRoll(), misc_commandscript::HandleMailBoxCommand(), Guild::HandleMemberDepositMoney(), Guild::HandleMemberLogout(), Guild::HandleMemberWithdrawMoney(), HandleMessagechatOpcode(), HandleMinimapPingOpcode(), mmaps_commandscript::HandleMmapLoadedTilesCommand(), mmaps_commandscript::HandleMmapLocCommand(), mmaps_commandscript::HandleMmapPathCommand(), mmaps_commandscript::HandleMmapStatsCommand(), mmaps_commandscript::HandleMmapTestArea(), modify_commandscript::HandleModifyPhaseCommand(), modify_commandscript::HandleModifyStandStateCommand(), modify_commandscript::HandleMorphResetCommand(), modify_commandscript::HandleMorphTargetCommand(), HandleMountSpecialAnimOpcode(), HandleMovementOpcodes(), HandleMoveSplineDoneOpcode(), HandleMoveTeleportAck(), HandleMoveTimeSkippedOpcode(), HandleMoveWorldportAck(), misc_commandscript::HandleNearGraveCommand(), HandleNextCinematicCamera(), npc_commandscript::HandleNpcAddCommand(), npc_commandscript::HandleNpcAddFormationCommand(), npc_commandscript::HandleNpcAddTempSpawnCommand(), npc_commandscript::HandleNpcAddVendorItemCommand(), npc_commandscript::HandleNpcFollowCommand(), npc_commandscript::HandleNpcMoveCommand(), npc_commandscript::HandleNpcNearCommand(), npc_commandscript::HandleNpcSetFactionTempIdCommand(), npc_commandscript::HandleNpcSetOriginalFaction(), npc_commandscript::HandleNpcTameCommand(), npc_commandscript::HandleNpcUnFollowCommand(), HandleOfferPetitionOpcode(), HandleOpenWrappedItemCallback(), HandleOptOutOfLootOpcode(), HandlePartyAssignmentOpcode(), HandlePetAction(), HandlePetActionHelper(), HandlePetCancelAuraOpcode(), HandlePetCastSpellOpcode(), pet_commandscript::HandlePetCreateCommand(), HandlePetitionBuyOpcode(), HandlePetitionSignOpcode(), pet_commandscript::HandlePetLearnCommand(), HandlePetSetAction(), HandlePetSpellAutocastOpcode(), HandlePetStopAttack(), pet_commandscript::HandlePetUnlearnCommand(), HandlePlayerLoginOpcode(), HandlePlayerLoginToCharInWorld(), misc_commandscript::HandlePossessCommand(), cheat_commandscript::HandlePowerCheatCommand(), HandleQueryGuildBankTabText(), HandleQueryInspectAchievements(), HandleQuestgiverAcceptQuestOpcode(), HandleQuestgiverHelloOpcode(), HandleQuestLogSwapQuest(), HandleRaidReadyCheckFinishedOpcode(), HandleRaidReadyCheckOpcode(), HandleRaidTargetUpdateOpcode(), HandleRandomRollOpcode(), Guild::HandleRemoveMember(), Guild::HandleRemoveRank(), HandleRepairItemOpcode(), HandleRepopRequestOpcode(), HandleReportLag(), HandleRequestVehicleExit(), reset_commandscript::HandleResetSpellsCommand(), reset_commandscript::HandleResetTalentsCommand(), misc_commandscript::HandleRespawnAllCommand(), misc_commandscript::HandleRespawnCommand(), HandleResurrectResponseOpcode(), Guild::HandleRoster(), misc_commandscript::HandleSaveCommand(), HandleSaveGuildEmblemOpcode(), HandleSellItemOpcode(), send_commandscript::HandleSendItemsCommand(), HandleSendMail(), send_commandscript::HandleSendMailCommand(), send_commandscript::HandleSendMoneyCommand(), HandleSetActionBarToggles(), HandleSetActionButtonOpcode(), HandleSetActiveMoverOpcode(), HandleSetChannelWatch(), Guild::HandleSetEmblem(), HandleSetFactionAtWar(), HandleSetFactionCheat(), HandleSetGuildBankTabText(), Guild::HandleSetInfo(), Guild::HandleSetLeader(), Guild::HandleSetMemberNote(), Guild::HandleSetMOTD(), Guild::HandleSetRankInfo(), HandleSetSavedInstanceExtend(), HandleSetTitleOpcode(), HandleSetWatchedFactionOpcode(), HandleSocketClosed(), spectator_commandscript::HandleSpectatorLeaveCommand(), spectator_commandscript::HandleSpectatorResetCommand(), ArenaSpectator::HandleSpectatorSpectateCommand(), spectator_commandscript::HandleSpectatorVersionCommand(), ArenaSpectator::HandleSpectatorWatchCommand(), HandleSpiritHealerActivateOpcode(), HandleStablePet(), HandleStableSwapPet(), misc_commandscript::HandleSummonCommand(), HandleTabardVendorActivateOpcode(), HandleTalentWipeConfirmOpcode(), cheat_commandscript::HandleTaxiCheatCommand(), HandleTaxiQueryAvailableNodes(), tele_commandscript::HandleTeleAddCommand(), tele_commandscript::HandleTeleCommand(), HandleTeleportTimeout(), HandleTextEmoteOpcode(), HandleTogglePvP(), HandleTotemDestroyed(), HandleTrainerBuySpellOpcode(), misc_commandscript::HandleUnbindSightCommand(), HandleUnlearnSkillOpcode(), misc_commandscript::HandleUnPossessCommand(), HandleUnstablePet(), misc_commandscript::HandleUnstuckCommand(), Guild::HandleUpdateMemberRank(), cheat_commandscript::HandleWaterWalkCheatCommand(), message_commandscript::HandleWhispersCommand(), HandleWhoisOpcode(), HandleWorldTeleportOpcode(), wp_commandscript::HandleWpAddCommand(), debug_commandscript::HandleWPGPSCommand(), wp_commandscript::HandleWpModifyCommand(), wp_commandscript::HandleWpShowCommand(), HandleZoneUpdateOpcode(), LogCommandUsage(), ArenaTeam::MassInviteToEvent(), Guild::MassInviteToEvent(), ChatHandler::needReportToTarget(), ServerMailReward::OnLogin(), MapSessionFilter::Process(), WorldSessionFilter::Process(), ReadMovementInfo(), ResetTimeOutTime(), SendActivateTaxiReply(), SendAttackStop(), SendAuctionHello(), Guild::SendBankTabsInfo(), SendBindPoint(), SendDiscoverNewTaxiNode(), SendDoFlight(), SendEnchantmentLog(), SendLearnNewTaxiNode(), SendLfgBootProposalUpdate(), SendLfgDisabled(), SendLfgJoinResult(), SendLfgLfrList(), SendLfgOfferContinue(), SendLfgPlayerReward(), SendLfgQueueStatus(), SendLfgRoleCheckUpdate(), SendLfgRoleChosen(), SendLfgTeleportError(), SendLfgUpdateProposal(), SendListInventory(), Guild::SendLoginInfo(), Guild::SendMoneyInfo(), Guild::SendPermissions(), SendPetitionShowList(), PlayerMenu::SendQuestGiverOfferReward(), PlayerMenu::SendQuestGiverQuestDetails(), PlayerMenu::SendQuestGiverRequestItems(), PlayerMenu::SendQuestQueryResponse(), SendStablePet(), SendTaxiMenu(), SendTaxiStatus(), SendTrainerList(), ChatHandler::SendWorldTextOptional(), ticket_commandscript::TicketResponseAppend(), Update(), World::UpdateSessions(), and ValidateHyperlinksAndMaybeKick().

◆ GetPlayerInfo()

std::string WorldSession::GetPlayerInfo ( ) const
192{
193 std::ostringstream ss;
194
195 ss << "[Player: ";
196
197 if (!m_playerLoading && _player)
198 {
199 ss << _player->GetName() << ' ' << _player->GetGUID().ToString() << ", ";
200 }
201
202 ss << "Account: " << GetAccountId() << "]";
203
204 return ss.str();
205}

References _player, GetAccountId(), Object::GetGUID(), WorldObject::GetName(), m_playerLoading, and ObjectGuid::ToString().

Referenced by Guild::_SendBankList(), Handle_Deprecated(), Handle_EarlyProccess(), Handle_NULL(), Handle_ServerSide(), HandleBattleFieldPortOpcode(), HandleChannelAnnouncements(), HandleChannelBan(), HandleChannelInvite(), HandleChannelKick(), HandleChannelList(), HandleChannelModerateOpcode(), HandleChannelModerator(), HandleChannelMute(), HandleChannelOwner(), HandleChannelPassword(), HandleChannelSetOwner(), HandleChannelUnban(), HandleChannelUnmoderator(), HandleChannelUnmute(), HandleCharFactionOrRaceChangeCallback(), HandleGetChannelMemberCount(), HandleGuildAddRankOpcode(), HandleGuildBankBuyTab(), HandleGuildBankDepositMoney(), HandleGuildBankerActivate(), HandleGuildBankLogQuery(), HandleGuildBankMoneyWithdrawn(), HandleGuildBankQueryTab(), HandleGuildBankUpdateTab(), HandleGuildBankWithdrawMoney(), HandleGuildChangeInfoTextOpcode(), HandleGuildCreateOpcode(), HandleGuildDeclineOpcode(), HandleGuildDelRankOpcode(), HandleGuildDemoteOpcode(), HandleGuildDisbandOpcode(), HandleGuildEventLogQueryOpcode(), HandleGuildInfoOpcode(), HandleGuildInviteOpcode(), HandleGuildLeaderOpcode(), HandleGuildLeaveOpcode(), HandleGuildMOTDOpcode(), HandleGuildPromoteOpcode(), HandleGuildQueryOpcode(), HandleGuildRankOpcode(), HandleGuildRemoveOpcode(), HandleGuildRosterOpcode(), HandleGuildSetOfficerNoteOpcode(), HandleGuildSetPublicNoteOpcode(), HandleJoinChannel(), HandleLeaveChannel(), HandleLfgGetStatus(), HandleLfgJoinOpcode(), HandleMessagechatOpcode(), WorldSocket::HandlePing(), Guild::HandleQuery(), HandleQueryGuildBankTabText(), Guild::HandleRoster(), HandleSaveGuildEmblemOpcode(), Guild::HandleSetBankTabInfo(), HandleSetGuildBankTabText(), Channel::List(), WorldSocket::LogOpcodeText(), LogUnexpectedOpcode(), LogUnprocessedTail(), WorldSocket::ReadDataHandler(), Guild::SendBankLog(), Guild::SendCommandResult(), Guild::SendEventLog(), Guild::SendInfo(), SendLfgPlayerReward(), SendLfgUpdateParty(), SendLfgUpdatePlayer(), Guild::SendLoginInfo(), Guild::SendMoneyInfo(), Guild::SendPermissions(), Guild::SendSaveEmblemResult(), Guild::BankTab::SendText(), Pet::Update(), and Update().

◆ GetPlayerName()

◆ GetQueryProcessor()

QueryCallbackProcessor & WorldSession::GetQueryProcessor ( )
inline
1077{ return _queryProcessor; }
QueryCallbackProcessor _queryProcessor
Definition: WorldSession.h:1087

References _queryProcessor.

Referenced by Player::ActivateSpec(), and ServerMailReward::OnLogin().

◆ GetRecruiterId()

◆ GetRemoteAddress()

◆ GetSecurity()

◆ GetSessionDbcLocale()

◆ GetSessionDbLocaleIndex()

◆ GetTotalTime()

uint32 WorldSession::GetTotalTime ( ) const
inline
376{ return m_total_time; }

References m_total_time.

Referenced by ~WorldSession().

◆ GetTutorialInt()

uint32 WorldSession::GetTutorialInt ( uint8  index) const
inline
458{ return m_Tutorials[index]; }

References m_Tutorials.

Referenced by HandleTutorialFlag().

◆ GetWarden()

Warden * WorldSession::GetWarden ( )
1303{
1304 return &(*_warden);
1305}

◆ Handle_Deprecated()

void WorldSession::Handle_Deprecated ( WorldPacket recvPacket)
822{
823 LOG_ERROR("network.opcode", "Received deprecated opcode {} from {}",
824 GetOpcodeNameForLogging(static_cast<OpcodeClient>(recvPacket.GetOpcode())), GetPlayerInfo());
825}
Opcodes
List of Opcodes.
Definition: Opcodes.h:30
std::string GetOpcodeNameForLogging(Opcodes opcode)
Lookup opcode name for human understandable logging.
Definition: Opcodes.cpp:1468
uint16 GetOpcode() const
Definition: WorldPacket.h:76
std::string GetPlayerInfo() const
Definition: WorldSession.cpp:191

References WorldPacket::GetOpcode(), GetOpcodeNameForLogging(), GetPlayerInfo(), and LOG_ERROR.

◆ Handle_EarlyProccess()

void WorldSession::Handle_EarlyProccess ( WorldPacket recvPacket)
810{
811 LOG_ERROR("network.opcode", "Received opcode {} that must be processed in WorldSocket::ReadDataHandler from {}",
812 GetOpcodeNameForLogging(static_cast<OpcodeClient>(recvPacket.GetOpcode())), GetPlayerInfo());
813}

References WorldPacket::GetOpcode(), GetOpcodeNameForLogging(), GetPlayerInfo(), and LOG_ERROR.

Referenced by OpcodeTable::Initialize().

◆ Handle_NULL()

void WorldSession::Handle_NULL ( WorldPacket null)
804{
805 LOG_ERROR("network.opcode", "Received unhandled opcode {} from {}",
807}

References WorldPacket::GetOpcode(), GetOpcodeNameForLogging(), GetPlayerInfo(), and LOG_ERROR.

Referenced by OpcodeTable::Initialize().

◆ Handle_ServerSide()

void WorldSession::Handle_ServerSide ( WorldPacket recvPacket)
816{
817 LOG_ERROR("network.opcode", "Received server-side opcode {} from {}",
818 GetOpcodeNameForLogging(static_cast<OpcodeServer>(recvPacket.GetOpcode())), GetPlayerInfo());
819}

References WorldPacket::GetOpcode(), GetOpcodeNameForLogging(), GetPlayerInfo(), and LOG_ERROR.

◆ HandleAcceptGrantLevel()

void WorldSession::HandleAcceptGrantLevel ( WorldPacket recvData)
67{
68 LOG_DEBUG("network", "WORLD: CMSG_ACCEPT_LEVEL_GRANT");
69
70 ObjectGuid guid;
71 recvData >> guid.ReadAsPacked();
72
74 if (!other)
75 return;
76
77 if (GetAccountId() != other->GetSession()->GetRecruiterId())
78 return;
79
80 if (other->GetGrantableLevels())
81 other->SetGrantableLevels(other->GetGrantableLevels() - 1);
82 else
83 return;
84
86}
Player * GetPlayer(Map const *, ObjectGuid const guid)
Definition: ObjectAccessor.cpp:220
Definition: ObjectGuid.h:118
PackedGuidReader ReadAsPacked()
Definition: ObjectGuid.h:135
void GiveLevel(uint8 level)
Definition: Player.cpp:2446
void SetGrantableLevels(uint8 val)
Definition: Player.h:2105
uint8 GetGrantableLevels()
Definition: Player.h:2104
uint32 GetRecruiterId() const
Definition: WorldSession.h:526

References _player, GetAccountId(), Player::GetGrantableLevels(), Unit::GetLevel(), ObjectAccessor::GetPlayer(), GetRecruiterId(), Player::GetSession(), Player::GiveLevel(), LOG_DEBUG, ObjectGuid::ReadAsPacked(), and Player::SetGrantableLevels().

Referenced by OpcodeTable::Initialize().

◆ HandleAcceptTradeOpcode()

void WorldSession::HandleAcceptTradeOpcode ( WorldPacket recvPacket)
247{
248 TradeData* my_trade = _player->m_trade;
249 if (!my_trade)
250 return;
251
252 Player* trader = my_trade->GetTrader();
253
254 TradeData* his_trade = trader->m_trade;
255 if (!his_trade)
256 return;
257
258 Item* myItems[TRADE_SLOT_TRADED_COUNT] = { nullptr, nullptr, nullptr, nullptr, nullptr, nullptr };
259 Item* hisItems[TRADE_SLOT_TRADED_COUNT] = { nullptr, nullptr, nullptr, nullptr, nullptr, nullptr };
260 bool myCanCompleteTrade = true, hisCanCompleteTrade = true;
261
262 // set before checks for propertly undo at problems (it already set in to client)
263 my_trade->SetAccepted(true);
264
265 // not accept case incorrect money amount
266 if (!_player->HasEnoughMoney(my_trade->GetMoney()))
267 {
269 my_trade->SetAccepted(false, true);
270 return;
271 }
272
273 // not accept case incorrect money amount
274 if (!trader->HasEnoughMoney(his_trade->GetMoney()))
275 {
277 his_trade->SetAccepted(false, true);
278 return;
279 }
280
281 if (_player->GetMoney() >= uint32(MAX_MONEY_AMOUNT) - his_trade->GetMoney())
282 {
284 my_trade->SetAccepted(false, true);
285 return;
286 }
287
288 if (trader->GetMoney() >= uint32(MAX_MONEY_AMOUNT) - my_trade->GetMoney())
289 {
290 trader->SendEquipError(EQUIP_ERR_TOO_MUCH_GOLD, nullptr, nullptr);
291 his_trade->SetAccepted(false, true);
292 return;
293 }
294
295 // not accept if some items now can't be trade (cheating)
296 for (uint8 i = 0; i < TRADE_SLOT_TRADED_COUNT; ++i)
297 {
298 if (Item* item = my_trade->GetItem(TradeSlots(i)))
299 {
300 if (!item->CanBeTraded(false, true))
301 {
303 return;
304 }
305
306 if (item->IsBindedNotWith(trader))
307 {
309 SendTradeStatus(TRADE_STATUS_CLOSE_WINDOW/*TRADE_STATUS_TRADE_CANCELED*/);
310 return;
311 }
312 }
313
314 if (Item* item = his_trade->GetItem(TradeSlots(i)))
315 {
316 if (!item->CanBeTraded(false, true))
317 {
319 return;
320 }
321 //if (item->IsBindedNotWith(_player)) // dont mark as invalid when his item isnt good (not exploitable because if item is invalid trade will fail anyway later on the same check)
322 //{
323 // SendTradeStatus(TRADE_STATUS_NOT_ELIGIBLE);
324 // his_trade->SetAccepted(false, true);
325 // return;
326 //}
327 }
328 }
329
330 if (his_trade->IsAccepted())
331 {
332 setAcceptTradeMode(my_trade, his_trade, myItems, hisItems);
333
334 Spell* my_spell = nullptr;
335 SpellCastTargets my_targets;
336
337 Spell* his_spell = nullptr;
338 SpellCastTargets his_targets;
339
340 // not accept if spell can't be casted now (cheating)
341 if (uint32 my_spell_id = my_trade->GetSpell())
342 {
343 SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(my_spell_id);
344 Item* castItem = my_trade->GetSpellCastItem();
345
346 if (!spellInfo || !his_trade->GetItem(TRADE_SLOT_NONTRADED) ||
347 (my_trade->HasSpellCastItem() && !castItem))
348 {
349 clearAcceptTradeMode(my_trade, his_trade);
350 clearAcceptTradeMode(myItems, hisItems);
351
352 my_trade->SetSpell(0);
353 return;
354 }
355
356 my_spell = new Spell(_player, spellInfo, TRIGGERED_FULL_MASK);
357 my_spell->m_CastItem = castItem;
358 my_targets.SetTradeItemTarget(_player);
359 my_spell->m_targets = my_targets;
360
361 SpellCastResult res = my_spell->CheckCast(true);
362 if (res != SPELL_CAST_OK)
363 {
364 my_spell->SendCastResult(res);
365
366 clearAcceptTradeMode(my_trade, his_trade);
367 clearAcceptTradeMode(myItems, hisItems);
368
369 delete my_spell;
370 my_trade->SetSpell(0);
371 return;
372 }
373 }
374
375 // not accept if spell can't be casted now (cheating)
376 if (uint32 his_spell_id = his_trade->GetSpell())
377 {
378 SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(his_spell_id);
379 Item* castItem = his_trade->GetSpellCastItem();
380
381 if (!spellInfo || !my_trade->GetItem(TRADE_SLOT_NONTRADED) || (his_trade->HasSpellCastItem() && !castItem))
382 {
383 delete my_spell;
384 his_trade->SetSpell(0);
385
386 clearAcceptTradeMode(my_trade, his_trade);
387 clearAcceptTradeMode(myItems, hisItems);
388 return;
389 }
390
391 his_spell = new Spell(trader, spellInfo, TRIGGERED_FULL_MASK);
392 his_spell->m_CastItem = castItem;
393 his_targets.SetTradeItemTarget(trader);
394 his_spell->m_targets = his_targets;
395
396 SpellCastResult res = his_spell->CheckCast(true);
397 if (res != SPELL_CAST_OK)
398 {
399 his_spell->SendCastResult(res);
400
401 clearAcceptTradeMode(my_trade, his_trade);
402 clearAcceptTradeMode(myItems, hisItems);
403
404 delete my_spell;
405 delete his_spell;
406
407 his_trade->SetSpell(0);
408 return;
409 }
410 }
411
412 // inform partner client
414
415 // test if item will fit in each inventory
416 hisCanCompleteTrade = (trader->CanStoreItems(myItems, TRADE_SLOT_TRADED_COUNT) == EQUIP_ERR_OK);
417 myCanCompleteTrade = (_player->CanStoreItems(hisItems, TRADE_SLOT_TRADED_COUNT) == EQUIP_ERR_OK);
418
419 clearAcceptTradeMode(myItems, hisItems);
420
421 // in case of missing space report error
422 if (!myCanCompleteTrade)
423 {
424 clearAcceptTradeMode(my_trade, his_trade);
425
428 my_trade->SetAccepted(false);
429 his_trade->SetAccepted(false);
430 delete my_spell;
431 delete his_spell;
432 return;
433 }
434 else if (!hisCanCompleteTrade)
435 {
436 clearAcceptTradeMode(my_trade, his_trade);
437
440 my_trade->SetAccepted(false);
441 his_trade->SetAccepted(false);
442 delete my_spell;
443 delete his_spell;
444 return;
445 }
446
447 // execute trade: 1. remove
448 for (uint8 i = 0; i < TRADE_SLOT_TRADED_COUNT; ++i)
449 {
450 if (myItems[i])
451 {
453 _player->MoveItemFromInventory(myItems[i]->GetBagSlot(), myItems[i]->GetSlot(), true);
454 }
455 if (hisItems[i])
456 {
457 hisItems[i]->SetGuidValue(ITEM_FIELD_GIFTCREATOR, trader->GetGUID());
458 trader->MoveItemFromInventory(hisItems[i]->GetBagSlot(), hisItems[i]->GetSlot(), true);
459 }
460 }
461
462 // execute trade: 2. store
463 moveItems(myItems, hisItems);
464
465 if (my_trade->GetMoney() >= 10 * GOLD )
466 {
467 CharacterDatabase.Execute("INSERT INTO log_money VALUES({}, {}, \"{}\", \"{}\", {}, \"{}\", {}, \"goods\", NOW(), {})",
468 GetAccountId(), _player->GetGUID().GetCounter(), _player->GetName(), GetRemoteAddress(), trader->GetSession()->GetAccountId(), trader->GetName(), my_trade->GetMoney(), 6);
469 }
470 if (his_trade->GetMoney() >= 10 * GOLD )
471 {
472 CharacterDatabase.Execute("INSERT INTO log_money VALUES({}, {}, \"{}\", \"{}\", {}, \"{}\", {}, \"goods\", NOW(), {})",
473 trader->GetSession()->GetAccountId(), trader->GetGUID().GetCounter(), trader->GetName(), trader->GetSession()->GetRemoteAddress(), GetAccountId(), _player->GetName(), his_trade->GetMoney(), 6);
474 }
475
476 // update money
477 _player->ModifyMoney(-int32(my_trade->GetMoney()));
478 _player->ModifyMoney(his_trade->GetMoney());
479 trader->ModifyMoney(-int32(his_trade->GetMoney()));
480 trader->ModifyMoney(my_trade->GetMoney());
481
482 if (my_spell)
483 my_spell->prepare(&my_targets);
484
485 if (his_spell)
486 his_spell->prepare(&his_targets);
487
488 // cleanup
489 clearAcceptTradeMode(my_trade, his_trade);
490 delete _player->m_trade;
491 _player->m_trade = nullptr;
492 delete trader->m_trade;
493 trader->m_trade = nullptr;
494
495 // desynchronized with the other saves here (SaveInventoryAndGoldToDB() not have own transaction guards)
496 CharacterDatabaseTransaction trans = CharacterDatabase.BeginTransaction();
498 trader->SaveInventoryAndGoldToDB(trans);
499 CharacterDatabase.CommitTransaction(trans);
500
503 }
504 else
505 {
507 }
508}
std::int32_t int32
Definition: Define.h:103
static void setAcceptTradeMode(TradeData *myTrade, TradeData *hisTrade, Item **myItems, Item **hisItems)
Definition: TradeHandler.cpp:203
static void clearAcceptTradeMode(TradeData *myTrade, TradeData *hisTrade)
Definition: TradeHandler.cpp:228
@ LANG_NOT_PARTNER_FREE_TRADE_SLOTS
Definition: Language.h:740
@ LANG_NOT_FREE_TRADE_SLOTS
Definition: Language.h:739
@ LANG_NOT_ENOUGH_GOLD
Definition: Language.h:738
@ ITEM_FIELD_GIFTCREATOR
Definition: UpdateFields.h:38
TradeSlots
Definition: TradeData.h:28
@ TRADE_SLOT_TRADED_COUNT
Definition: TradeData.h:30
@ TRADE_SLOT_NONTRADED
Definition: TradeData.h:31
#define MAX_MONEY_AMOUNT
Definition: Player.h:930
@ EQUIP_ERR_TOO_MUCH_GOLD
Definition: Item.h:123
@ EQUIP_ERR_OK
Definition: Item.h:47
@ TRIGGERED_FULL_MASK
Will return SPELL_FAILED_DONT_REPORT in CheckCast functions.
Definition: SpellDefines.h:147
#define sSpellMgr
Definition: SpellMgr.h:825
SQLTransaction< CharacterDatabaseConnection > CharacterDatabaseTransaction
Definition: DatabaseEnvFwd.h:69
DatabaseWorkerPool< CharacterDatabaseConnection > CharacterDatabase
Accessor to the character database.
Definition: DatabaseEnv.cpp:21
@ TRADE_STATUS_TRADE_COMPLETE
Definition: SharedDefines.h:3558
@ TRADE_STATUS_TRADE_ACCEPT
Definition: SharedDefines.h:3554
@ TRADE_STATUS_TRADE_CANCELED
Definition: SharedDefines.h:3553
@ TRADE_STATUS_NOT_ELIGIBLE
Definition: SharedDefines.h:3573
@ TRADE_STATUS_CLOSE_WINDOW
Definition: SharedDefines.h:3562
@ GOLD
Definition: SharedDefines.h:253
SpellCastResult
Definition: SharedDefines.h:948
@ SPELL_CAST_OK
Definition: SharedDefines.h:1138
Definition: Chat.h:38
void SendNotification(std::string_view str)
Definition: Chat.cpp:104
void SetGuidValue(uint16 index, ObjectGuid value)
Definition: Object.cpp:723
void SaveInventoryAndGoldToDB(CharacterDatabaseTransaction trans)
Definition: PlayerStorage.cpp:7122
bool ModifyMoney(int32 amount, bool sendError=true)
Definition: Player.cpp:11514
TradeData * m_trade
Definition: Player.h:2821
bool HasEnoughMoney(uint32 amount) const
Definition: Player.h:1600
void MoveItemFromInventory(uint8 bag, uint8 slot, bool update)
Definition: PlayerStorage.cpp:2980
uint32 GetMoney() const
Definition: Player.h:1598
void SendEquipError(InventoryResult msg, Item *pItem, Item *pItem2=nullptr, uint32 itemid=0)
Definition: PlayerStorage.cpp:4023
InventoryResult CanStoreItems(Item **pItem, int32 count) const
Definition: PlayerStorage.cpp:1541
Definition: TradeData.h:36
Item * GetSpellCastItem() const
Definition: TradeData.cpp:49
bool HasSpellCastItem() const
Definition: TradeData.h:53
void SetSpell(uint32 spell_id, Item *castItem=nullptr)
Definition: TradeData.cpp:76
Player * GetTrader() const
Definition: TradeData.h:41
uint32 GetMoney() const
Definition: TradeData.h:55
Item * GetItem(TradeSlots slot) const
Definition: TradeData.cpp:26
bool IsAccepted() const
Definition: TradeData.h:58
uint32 GetSpell() const
Definition: TradeData.h:49
void SetAccepted(bool state, bool crosssend=false)
Definition: TradeData.cpp:120
void moveItems(Item *myItems[], Item *hisItems[])
Definition: TradeHandler.cpp:134
std::string const & GetRemoteAddress()
Definition: WorldSession.h:371
void SendTradeStatus(TradeStatus status)
Definition: TradeHandler.cpp:33
Definition: Spell.h:109
void SetTradeItemTarget(Player *caster)
Definition: Spell.cpp:338
Definition: Spell.h:284
SpellCastTargets m_targets
Definition: Spell.h:527
SpellCastResult prepare(SpellCastTargets const *targets, AuraEffect const *triggeredByAura=nullptr)
Definition: Spell.cpp:3475
SpellCastResult CheckCast(bool strict)
Definition: Spell.cpp:5651
static void SendCastResult(Player *caster, SpellInfo const *spellInfo, uint8 castCount, SpellCastResult result, SpellCustomErrors customError=SPELL_CUSTOM_ERROR_NONE)
Definition: Spell.cpp:4667
Item * m_CastItem
Definition: Spell.h:521
Definition: SpellInfo.h:316

References _player, Player::CanStoreItems(), CharacterDatabase, Spell::CheckCast(), clearAcceptTradeMode(), EQUIP_ERR_OK, EQUIP_ERR_TOO_MUCH_GOLD, GetAccountId(), ObjectGuid::GetCounter(), Object::GetGUID(), TradeData::GetItem(), Player::GetMoney(), TradeData::GetMoney(), WorldObject::GetName(), GetRemoteAddress(), Player::GetSession(), TradeData::GetSpell(), TradeData::GetSpellCastItem(), TradeData::GetTrader(), GOLD, Player::HasEnoughMoney(), TradeData::HasSpellCastItem(), TradeData::IsAccepted(), ITEM_FIELD_GIFTCREATOR, LANG_NOT_ENOUGH_GOLD, LANG_NOT_FREE_TRADE_SLOTS, LANG_NOT_PARTNER_FREE_TRADE_SLOTS, Spell::m_CastItem, Spell::m_targets, Player::m_trade, MAX_MONEY_AMOUNT, Player::ModifyMoney(), Player::MoveItemFromInventory(), moveItems(), Spell::prepare(), Player::SaveInventoryAndGoldToDB(), Spell::SendCastResult(), Player::SendEquipError(), ChatHandler::SendNotification(), SendTradeStatus(), TradeData::SetAccepted(), setAcceptTradeMode(), Object::SetGuidValue(), TradeData::SetSpell(), SpellCastTargets::SetTradeItemTarget(), SPELL_CAST_OK, sSpellMgr, TRADE_SLOT_NONTRADED, TRADE_SLOT_TRADED_COUNT, TRADE_STATUS_CLOSE_WINDOW, TRADE_STATUS_NOT_ELIGIBLE, TRADE_STATUS_TRADE_ACCEPT, TRADE_STATUS_TRADE_CANCELED, TRADE_STATUS_TRADE_COMPLETE, and TRIGGERED_FULL_MASK.

Referenced by OpcodeTable::Initialize().

◆ HandleActivateTaxiExpressOpcode()

void WorldSession::HandleActivateTaxiExpressOpcode ( WorldPacket recvPacket)
161{
162 ObjectGuid guid;
163 uint32 node_count;
164
165 recvData >> guid >> node_count;
166
168 if (!npc)
169 {
170 LOG_DEBUG("network", "WORLD: HandleActivateTaxiExpressOpcode - Unit ({}) not found or you can't interact with it.", guid.ToString());
172 return;
173 }
174 std::vector<uint32> nodes;
175
176 for (uint32 i = 0; i < node_count; ++i)
177 {
178 uint32 node;
179 recvData >> node;
180
181 if (!GetPlayer()->m_taxi.IsTaximaskNodeKnown(node) && !GetPlayer()->isTaxiCheater())
182 {
184 recvData.rfinish();
185 return;
186 }
187
188 nodes.push_back(node);
189 }
190
191 if (nodes.empty())
192 return;
193
194 LOG_DEBUG("network", "WORLD: Received CMSG_ACTIVATETAXIEXPRESS from {} to {}", nodes.front(), nodes.back());
195
196 GetPlayer()->ActivateTaxiPathTo(nodes, npc, 0);
197}
npc
Definition: BattlegroundSA.h:75
@ UNIT_NPC_FLAG_FLIGHTMASTER
Definition: UnitDefines.h:307
@ ERR_TAXINOTVISITED
Definition: SharedDefines.h:3601
@ ERR_TAXITOOFARAWAY
Definition: SharedDefines.h:3599
bool ActivateTaxiPathTo(std::vector< uint32 > const &nodes, Creature *npc=nullptr, uint32 spellid=1)
Definition: Player.cpp:10230
void SendActivateTaxiReply(ActivateTaxiReply reply)
Definition: TaxiHandler.cpp:279

References Player::ActivateTaxiPathTo(), ERR_TAXINOTVISITED, ERR_TAXITOOFARAWAY, Player::GetNPCIfCanInteractWith(), GetPlayer(), LOG_DEBUG, ByteBuffer::rfinish(), SendActivateTaxiReply(), ObjectGuid::ToString(), and UNIT_NPC_FLAG_FLIGHTMASTER.

Referenced by OpcodeTable::Initialize().

◆ HandleActivateTaxiOpcode()

void WorldSession::HandleActivateTaxiOpcode ( WorldPacket recvPacket)
252{
253 ObjectGuid guid;
254 std::vector<uint32> nodes;
255 nodes.resize(2);
256 GetPlayer()->SetCanTeleport(true);
257 recvData >> guid >> nodes[0] >> nodes[1];
258 LOG_DEBUG("network", "WORLD: Received CMSG_ACTIVATETAXI from {} to {}", nodes[0], nodes[1]);
260 if (!npc)
261 {
262 LOG_DEBUG("network", "WORLD: HandleActivateTaxiOpcode - Unit ({}) not found or you can't interact with it.", guid.ToString());
264 return;
265 }
266
267 if (!GetPlayer()->isTaxiCheater())
268 {
269 if (!GetPlayer()->m_taxi.IsTaximaskNodeKnown(nodes[0]) || !GetPlayer()->m_taxi.IsTaximaskNodeKnown(nodes[1]))
270 {
272 return;
273 }
274 }
275
276 GetPlayer()->ActivateTaxiPathTo(nodes, npc, 0);
277}
void SetCanTeleport(bool value)
Definition: Player.h:2480

References Player::ActivateTaxiPathTo(), ERR_TAXINOTVISITED, ERR_TAXITOOFARAWAY, Player::GetNPCIfCanInteractWith(), GetPlayer(), LOG_DEBUG, SendActivateTaxiReply(), Player::SetCanTeleport(), ObjectGuid::ToString(), and UNIT_NPC_FLAG_FLIGHTMASTER.

Referenced by OpcodeTable::Initialize().

◆ HandleAddFriendOpcode()

void WorldSession::HandleAddFriendOpcode ( WorldPacket recvPacket)
38{
39 std::string friendName = GetAcoreString(LANG_FRIEND_IGNORE_UNKNOWN);
40 std::string friendNote;
41
42 recv_data >> friendName;
43 recv_data >> friendNote;
44
45 if (!normalizePlayerName(friendName))
46 return;
47
48 ObjectGuid friendGuid = sCharacterCache->GetCharacterGuidByName(friendName);
49 if (!friendGuid)
50 return;
51
52 CharacterCacheEntry const* playerData = sCharacterCache->GetCharacterCacheByGuid(friendGuid);
53 if (!playerData)
54 return;
55
56 uint32 friendAccountId = playerData->AccountId;
57 TeamId teamId = Player::TeamIdForRace(playerData->Race);
58 FriendsResult friendResult = FRIEND_NOT_FOUND;
59
61 {
62 if (friendGuid)
63 {
64 if (friendGuid == GetPlayer()->GetGUID())
65 friendResult = FRIEND_SELF;
67 friendResult = FRIEND_ENEMY;
68 else if (GetPlayer()->GetSocial()->HasFriend(friendGuid))
69 friendResult = FRIEND_ALREADY;
70 else
71 {
72 Player* pFriend = ObjectAccessor::FindConnectedPlayer(friendGuid);
73 if (pFriend && pFriend->IsVisibleGloballyFor(GetPlayer()) && !pFriend->GetSession()->IsGMAccount())
74 friendResult = FRIEND_ADDED_ONLINE;
75 else
76 friendResult = FRIEND_ADDED_OFFLINE;
77 if (GetPlayer()->GetSocial()->AddToSocialList(friendGuid, SOCIAL_FLAG_FRIEND))
78 GetPlayer()->GetSocial()->SetFriendNote(friendGuid, friendNote);
79 else
80 friendResult = FRIEND_LIST_FULL;
81 }
82 GetPlayer()->GetSocial()->SetFriendNote(friendGuid, friendNote);
83 }
84 }
85
86 sSocialMgr->SendFriendStatus(GetPlayer(), friendResult, friendGuid, false);
87
88 LOG_DEBUG("network", "WORLD: Sent (SMSG_FRIEND_STATUS)");
89}
bool normalizePlayerName(std::string &name)
Definition: ObjectMgr.cpp:206
#define sCharacterCache
Definition: CharacterCache.h:83
@ CONFIG_ALLOW_GM_FRIEND
Definition: IWorld.h:89
@ CONFIG_ALLOW_TWO_SIDE_ADD_FRIEND
Definition: IWorld.h:81
@ LANG_FRIEND_IGNORE_UNKNOWN
Definition: Language.h:80
FriendsResult
Results of friend related commands.
Definition: SocialMgr.h:65
@ FRIEND_ENEMY
Definition: SocialMgr.h:76
@ FRIEND_ALREADY
Definition: SocialMgr.h:74
@ FRIEND_ADDED_OFFLINE
Definition: SocialMgr.h:73
@ FRIEND_NOT_FOUND
Definition: SocialMgr.h:70
@ FRIEND_ADDED_ONLINE
Definition: SocialMgr.h:72
@ FRIEND_SELF
Definition: SocialMgr.h:75
@ FRIEND_LIST_FULL
Definition: SocialMgr.h:67
#define sSocialMgr
Definition: SocialMgr.h:147
@ SOCIAL_FLAG_FRIEND
Definition: SocialMgr.h:39
TeamId GetTeamId(PvPTeamId teamId)
Definition: SharedDefines.h:3462
TeamId
Definition: SharedDefines.h:759
Realm realm
Definition: World.cpp:111
bool IsPlayerAccount(uint32 gmlevel)
Definition: AccountMgr.cpp:305
uint32 GetSecurity(uint32 accountId)
Definition: AccountMgr.cpp:238
Player * FindConnectedPlayer(ObjectGuid const guid)
Definition: ObjectAccessor.cpp:257
Definition: CharacterCache.h:28
uint8 Race
Definition: CharacterCache.h:33
uint32 AccountId
Definition: CharacterCache.h:31
static TeamId TeamIdForRace(uint8 race)
Definition: Player.cpp:5830
bool IsVisibleGloballyFor(Player const *player) const
Definition: Player.cpp:11485
PlayerSocial * GetSocial()
Definition: Player.h:1141
void SetFriendNote(ObjectGuid friendGuid, std::string note)
Definition: SocialMgr.cpp:105
bool IsGMAccount() const
Definition: WorldSession.cpp:181
char const * GetAcoreString(uint32 entry) const
Definition: WorldSession.cpp:793
uint32 Realm
Definition: Realm.h:43
RealmHandle Id
Definition: Realm.h:69

References CharacterCacheEntry::AccountId, CONFIG_ALLOW_GM_FRIEND, CONFIG_ALLOW_TWO_SIDE_ADD_FRIEND, ObjectAccessor::FindConnectedPlayer(), FRIEND_ADDED_OFFLINE, FRIEND_ADDED_ONLINE, FRIEND_ALREADY, FRIEND_ENEMY, FRIEND_LIST_FULL, FRIEND_NOT_FOUND, FRIEND_SELF, GetAcoreString(), GetPlayer(), GetSecurity(), AccountMgr::GetSecurity(), Player::GetSession(), Player::GetSocial(), GetTeamId(), Realm::Id, IsGMAccount(), AccountMgr::IsPlayerAccount(), Player::IsVisibleGloballyFor(), LANG_FRIEND_IGNORE_UNKNOWN, LOG_DEBUG, normalizePlayerName(), CharacterCacheEntry::Race, realm, RealmHandle::Realm, sCharacterCache, PlayerSocial::SetFriendNote(), SOCIAL_FLAG_FRIEND, sSocialMgr, sWorld, and Player::TeamIdForRace().

Referenced by OpcodeTable::Initialize().

◆ HandleAddIgnoreOpcode()

void WorldSession::HandleAddIgnoreOpcode ( WorldPacket recvPacket)
104{
105 std::string ignoreName = GetAcoreString(LANG_FRIEND_IGNORE_UNKNOWN);
106
107 recv_data >> ignoreName;
108
109 if (!normalizePlayerName(ignoreName))
110 return;
111
112 LOG_DEBUG("network", "WORLD: {} asked to Ignore: '{}'", GetPlayer()->GetName(), ignoreName);
113
114 ObjectGuid ignoreGuid = sCharacterCache->GetCharacterGuidByName(ignoreName);
115 if (!ignoreGuid)
116 return;
117
118 FriendsResult ignoreResult;
119
120 if (ignoreGuid == GetPlayer()->GetGUID()) //not add yourself
121 ignoreResult = FRIEND_IGNORE_SELF;
122 else if (GetPlayer()->GetSocial()->HasIgnore(ignoreGuid))
123 ignoreResult = FRIEND_IGNORE_ALREADY;
124 else
125 {
126 ignoreResult = FRIEND_IGNORE_ADDED;
127
128 // ignore list full
129 if (!GetPlayer()->GetSocial()->AddToSocialList(ignoreGuid, SOCIAL_FLAG_IGNORED))
130 ignoreResult = FRIEND_IGNORE_FULL;
131 }
132
133 sSocialMgr->SendFriendStatus(GetPlayer(), ignoreResult, ignoreGuid, false);
134
135 LOG_DEBUG("network", "WORLD: Sent (SMSG_FRIEND_STATUS)");
136}
@ FRIEND_IGNORE_FULL
Definition: SocialMgr.h:77
@ FRIEND_IGNORE_ADDED
Definition: SocialMgr.h:81
@ FRIEND_IGNORE_SELF
Definition: SocialMgr.h:78
@ FRIEND_IGNORE_ALREADY
Definition: SocialMgr.h:80
@ SOCIAL_FLAG_IGNORED
Definition: SocialMgr.h:40

References FRIEND_IGNORE_ADDED, FRIEND_IGNORE_ALREADY, FRIEND_IGNORE_FULL, FRIEND_IGNORE_SELF, GetAcoreString(), GetPlayer(), LANG_FRIEND_IGNORE_UNKNOWN, LOG_DEBUG, normalizePlayerName(), sCharacterCache, SOCIAL_FLAG_IGNORED, and sSocialMgr.

Referenced by OpcodeTable::Initialize().

◆ HandleAlterAppearance()

void WorldSession::HandleAlterAppearance ( WorldPacket recvData)
1502{
1503 LOG_DEBUG("network", "CMSG_ALTER_APPEARANCE");
1504
1505 uint32 Hair, Color, FacialHair, SkinColor;
1506 recvData >> Hair >> Color >> FacialHair >> SkinColor;
1507
1508 BarberShopStyleEntry const* bs_hair = sBarberShopStyleStore.LookupEntry(Hair);
1509
1510 if (!bs_hair || bs_hair->type != 0 || bs_hair->race != _player->getRace() || bs_hair->gender != _player->getGender())
1511 return;
1512
1513 BarberShopStyleEntry const* bs_facialHair = sBarberShopStyleStore.LookupEntry(FacialHair);
1514
1515 if (!bs_facialHair || bs_facialHair->type != 2 || bs_facialHair->race != _player->getRace() || bs_facialHair->gender != _player->getGender())
1516 return;
1517
1518 BarberShopStyleEntry const* bs_skinColor = sBarberShopStyleStore.LookupEntry(SkinColor);
1519
1520 if (bs_skinColor && (bs_skinColor->type != 3 || bs_skinColor->race != _player->getRace() || bs_skinColor->gender != _player->getGender()))
1521 return;
1522
1524 if (!go)
1525 {
1527 data << uint32(2);
1528 SendPacket(&data);
1529 return;
1530 }
1531
1533 {
1535 data << uint32(2);
1536 SendPacket(&data);
1537 return;
1538 }
1539
1540 uint32 cost = _player->GetBarberShopCost(bs_hair->hair_id, Color, bs_facialHair->hair_id, bs_skinColor);
1541
1542 // 0 - ok
1543 // 1, 3 - not enough money
1544 // 2 - you have to seat on barber chair
1545 if (!_player->HasEnoughMoney(cost))
1546 {
1548 data << uint32(1); // no money
1549 SendPacket(&data);
1550 return;
1551 }
1552 else
1553 {
1555 data << uint32(0); // ok
1556 SendPacket(&data);
1557 }
1558
1559 _player->ModifyMoney(-int32(cost)); // it isn't free
1561
1564 _player->SetByteValue(PLAYER_BYTES_2, 0, uint8(bs_facialHair->hair_id));
1565 if (bs_skinColor)
1566 _player->SetByteValue(PLAYER_BYTES, 0, uint8(bs_skinColor->hair_id));
1567
1569
1570 _player->SetStandState(0); // stand up
1571}
DBCStorage< BarberShopStyleEntry > sBarberShopStyleStore(BarberShopStyleEntryfmt)
@ UNIT_STAND_STATE_SIT_LOW_CHAIR
Definition: UnitDefines.h:36
@ PLAYER_BYTES_2
Definition: UpdateFields.h:182
@ PLAYER_BYTES
Definition: UpdateFields.h:181
@ GAMEOBJECT_TYPE_BARBER_CHAIR
Definition: SharedDefines.h:1592
@ ACHIEVEMENT_CRITERIA_TYPE_VISIT_BARBER_SHOP
Definition: DBCEnums.h:162
@ ACHIEVEMENT_CRITERIA_TYPE_GOLD_SPENT_AT_BARBER
Definition: DBCEnums.h:177
@ SMSG_BARBER_SHOP_RESULT
Definition: Opcodes.h:1094
uint32 chairheight
Definition: GameObjectData.h:345
struct GameObjectTemplate::@227::@254 barberChair
void SetByteValue(uint16 index, uint8 offset, uint8 value)
Definition: Object.cpp:750
GameObject * FindNearestGameObjectOfType(GameobjectTypes type, float range) const
Definition: Object.cpp:2464
uint32 GetBarberShopCost(uint8 newhairstyle, uint8 newhaircolor, uint8 newfacialhair, BarberShopStyleEntry const *newSkin=nullptr)
Definition: Player.cpp:13251
void UpdateAchievementCriteria(AchievementCriteriaTypes type, uint32 miscValue1=0, uint32 miscValue2=0, Unit *unit=nullptr)
Definition: PlayerUpdates.cpp:2127
uint8 getGender() const
Definition: Unit.h:752
uint8 getRace(bool original=false) const
Definition: Unit.cpp:20981
uint8 getStandState() const
Definition: Unit.h:982
void SetStandState(uint8 state)
Definition: Unit.cpp:16691
void SendPacket(WorldPacket const *packet)
Send a packet to the client.
Definition: WorldSession.cpp:214
Definition: DBCStructure.h:589
uint32 type
Definition: DBCStructure.h:591
uint32 race
Definition: DBCStructure.h:597
uint32 gender
Definition: DBCStructure.h:598
uint32 hair_id
Definition: DBCStructure.h:599

References _player, ACHIEVEMENT_CRITERIA_TYPE_GOLD_SPENT_AT_BARBER, ACHIEVEMENT_CRITERIA_TYPE_VISIT_BARBER_SHOP, GameObjectTemplate::barberChair, GameObjectTemplate::chairheight, WorldObject::FindNearestGameObjectOfType(), GAMEOBJECT_TYPE_BARBER_CHAIR, BarberShopStyleEntry::gender, Player::GetBarberShopCost(), Unit::getGender(), GameObject::GetGOInfo(), Unit::getRace(), Unit::getStandState(), BarberShopStyleEntry::hair_id, Player::HasEnoughMoney(), LOG_DEBUG, Player::ModifyMoney(), PLAYER_BYTES, PLAYER_BYTES_2, BarberShopStyleEntry::race, sBarberShopStyleStore, SendPacket(), Object::SetByteValue(), Unit::SetStandState(), SMSG_BARBER_SHOP_RESULT, BarberShopStyleEntry::type, UNIT_STAND_STATE_SIT_LOW_CHAIR, and Player::UpdateAchievementCriteria().

Referenced by OpcodeTable::Initialize().

◆ HandleAreaSpiritHealerQueryOpcode()

void WorldSession::HandleAreaSpiritHealerQueryOpcode ( WorldPacket recvData)
1660{
1661 LOG_DEBUG("network", "WORLD: CMSG_AREA_SPIRIT_HEALER_QUERY");
1662
1664
1665 ObjectGuid guid;
1666 recv_data >> guid;
1667
1668 Creature* unit = GetPlayer()->GetMap()->GetCreature(guid);
1669 if (!unit)
1670 return;
1671
1672 if (!unit->IsSpiritService()) // it's not spirit service
1673 return;
1674
1675 if (bg)
1676 sBattlegroundMgr->SendAreaSpiritHealerQueryOpcode(_player, bg, guid);
1677
1678 if (Battlefield* bf = sBattlefieldMgr->GetBattlefieldToZoneId(_player->GetZoneId()))
1679 bf->SendAreaSpiritHealerQueryOpcode(_player, guid);
1680}
#define sBattlegroundMgr
Definition: BattlegroundMgr.h:186
#define sBattlefieldMgr
Definition: BattlefieldMgr.h:77
Definition: Battlefield.h:204
Definition: Battleground.h:303
Battleground * GetBattleground(bool create=false) const
Definition: Player.cpp:12195
bool IsSpiritService() const
Definition: Unit.h:737

References _player, Player::GetBattleground(), Map::GetCreature(), WorldObject::GetMap(), GetPlayer(), WorldObject::GetZoneId(), Unit::IsSpiritService(), LOG_DEBUG, sBattlefieldMgr, and sBattlegroundMgr.

Referenced by OpcodeTable::Initialize().

◆ HandleAreaSpiritHealerQueueOpcode()

void WorldSession::HandleAreaSpiritHealerQueueOpcode ( WorldPacket recvData)
1683{
1684 LOG_DEBUG("network", "WORLD: CMSG_AREA_SPIRIT_HEALER_QUEUE");
1685
1687
1688 ObjectGuid guid;
1689 recv_data >> guid;
1690
1691 Creature* unit = GetPlayer()->GetMap()->GetCreature(guid);
1692 if (!unit)
1693 return;
1694
1695 if (!unit->IsSpiritService()) // it's not spirit service
1696 return;
1697
1698 if (bg)
1700
1701 if (Battlefield* bf = sBattlefieldMgr->GetBattlefieldToZoneId(_player->GetZoneId()))
1702 bf->AddPlayerToResurrectQueue(guid, _player->GetGUID());
1703}
void AddPlayerToResurrectQueue(ObjectGuid npc_guid, ObjectGuid player_guid)
Definition: Battleground.cpp:1360

References _player, Battleground::AddPlayerToResurrectQueue(), Player::GetBattleground(), Map::GetCreature(), Object::GetGUID(), WorldObject::GetMap(), GetPlayer(), WorldObject::GetZoneId(), Unit::IsSpiritService(), LOG_DEBUG, and sBattlefieldMgr.

Referenced by OpcodeTable::Initialize().

◆ HandleAreaTriggerOpcode()

void WorldSession::HandleAreaTriggerOpcode ( WorldPacket recvPacket)
730{
731 uint32 triggerId;
732 recv_data >> triggerId;
733
734 LOG_DEBUG("network", "CMSG_AREATRIGGER. Trigger ID: {}", triggerId);
735
736 Player* player = GetPlayer();
737 if (player->IsInFlight())
738 {
739 LOG_DEBUG("network", "HandleAreaTriggerOpcode: Player '{}' ({}) in flight, ignore Area Trigger ID:{}",
740 player->GetName(), player->GetGUID().ToString(), triggerId);
741 return;
742 }
743
744 AreaTrigger const* atEntry = sObjectMgr->GetAreaTrigger(triggerId);
745 if (!atEntry)
746 {
747 LOG_DEBUG("network", "HandleAreaTriggerOpcode: Player '{}' ({}) send unknown (by DBC) Area Trigger ID:{}",
748 player->GetName(), player->GetGUID().ToString(), triggerId);
749 return;
750 }
751
752 uint32 teamFaction = player->GetTeamId(true) == TEAM_ALLIANCE ? FACTION_MASK_ALLIANCE : FACTION_MASK_HORDE;
753 bool isTavernAreatrigger = sObjectMgr->IsTavernAreaTrigger(triggerId, teamFaction);
754 if (!player->IsInAreaTriggerRadius(atEntry, isTavernAreatrigger ? 5.f : 0.f))
755 {
756 LOG_DEBUG("network", "HandleAreaTriggerOpcode: Player {} ({}) too far (trigger map: {} player map: {}), ignore Area Trigger ID: {}",
757 player->GetName(), player->GetGUID().ToString(), atEntry->map, player->GetMapId(), triggerId);
758 return;
759 }
760
761 if (player->isDebugAreaTriggers)
763
764 if (sScriptMgr->OnAreaTrigger(player, atEntry))
765 return;
766
767 if (player->IsAlive())
768 if (uint32 questId = sObjectMgr->GetQuestForAreaTrigger(triggerId))
769 if (player->GetQuestStatus(questId) == QUEST_STATUS_INCOMPLETE)
770 player->AreaExploredOrEventHappens(questId);
771
772 if (isTavernAreatrigger)
773 {
774 // set resting flag we are in the inn
775 player->SetRestFlag(REST_FLAG_IN_TAVERN, atEntry->entry);
776
777 if (sWorld->IsFFAPvPRealm())
778 {
780 {
782 sScriptMgr->OnFfaPvpStateUpdate(player, false);
783
784 }
785 }
786 return;
787 }
788
789 if (Battleground* bg = player->GetBattleground())
790 if (bg->GetStatus() == STATUS_IN_PROGRESS)
791 {
792 bg->HandleAreaTrigger(player, triggerId);
793 return;
794 }
795
796 if (OutdoorPvP* pvp = player->GetOutdoorPvP())
797 if (pvp->HandleAreaTrigger(_player, triggerId))
798 return;
799
800 AreaTriggerTeleport const* at = sObjectMgr->GetAreaTriggerTeleport(triggerId);
801 if (!at)
802 return;
803
804 bool teleported = false;
805 if (player->GetMapId() != at->target_mapId)
806 {
807 if (Map::EnterState denyReason = sMapMgr->PlayerCannotEnter(at->target_mapId, player, false))
808 {
809 bool reviveAtTrigger = false; // should we revive the player if he is trying to enter the correct instance?
810 switch (denyReason)
811 {
817 reviveAtTrigger = true;
818 break;
819 default:
820 break;
821 }
822
823 if (reviveAtTrigger) // check if the player is touching the areatrigger leading to the map his corpse is on
824 {
825 if (!player->IsAlive() && player->HasCorpse())
826 {
827 if (player->GetCorpseLocation().GetMapId() == at->target_mapId)
828 {
829 player->ResurrectPlayer(0.5f);
830 player->SpawnCorpseBones();
831 }
832 }
833 }
834
835 return;
836 }
837
838 if (Group* group = player->GetGroup())
839 if (group->isLFGGroup() && player->GetMap()->IsDungeon())
840 teleported = player->TeleportToEntryPoint();
841 }
842
843 if (!teleported)
845}
#define sScriptMgr
Definition: ScriptMgr.h:708
@ STATUS_IN_PROGRESS
Definition: Battleground.h:202
#define sMapMgr
Definition: MapMgr.h:221
@ QUEST_STATUS_INCOMPLETE
Definition: QuestDef.h:103
@ LANG_DEBUG_AREATRIGGER_REACHED
Definition: Language.h:981
@ UNIT_BYTE2_FLAG_FFA_PVP
Definition: UnitDefines.h:117
@ UNIT_FIELD_BYTES_2
Definition: UpdateFields.h:161
@ TELE_TO_NOT_LEAVE_TRANSPORT
Definition: Player.h:822
@ REST_FLAG_IN_TAVERN
Definition: Player.h:814
@ TEAM_ALLIANCE
Definition: SharedDefines.h:760
@ FACTION_MASK_ALLIANCE
Definition: DBCEnums.h:338
@ FACTION_MASK_HORDE
Definition: DBCEnums.h:339
void PSendSysMessage(std::string_view str, bool escapeCharacters=false)
Definition: Chat.cpp:210
void RemoveByteFlag(uint16 index, uint8 offset, uint8 newFlag)
Definition: Object.cpp:930
bool HasByteFlag(uint16 index, uint8 offset, uint8 flag) const
Definition: Object.cpp:949
uint32 GetMapId() const
Definition: Position.h:276
void SetRestFlag(RestFlag restFlag, uint32 triggerId=0)
Definition: Player.cpp:16154
TeamId GetTeamId(bool original=false) const
Definition: Player.h:2090
void SpawnCorpseBones(bool triggerSave=true)
Definition: Player.cpp:4672
bool HasCorpse() const
Definition: Player.h:2020
bool TeleportToEntryPoint()
Definition: Player.cpp:1597
OutdoorPvP * GetOutdoorPvP() const
Definition: Player.cpp:12512
WorldLocation GetCorpseLocation() const
Definition: Player.h:2021
bool TeleportTo(uint32 mapid, float x, float y, float z, float orientation, uint32 options=0, Unit *target=nullptr, bool newInstance=false)
Definition: Player.cpp:1330
void AreaExploredOrEventHappens(uint32 questId)
Definition: PlayerQuest.cpp:1785
QuestStatus GetQuestStatus(uint32 quest_id) const
Definition: PlayerQuest.cpp:1424
bool isDebugAreaTriggers
Definition: Player.h:2538
bool IsInAreaTriggerRadius(AreaTrigger const *trigger, float delta=0.f) const
Definition: Player.cpp:2183
void ResurrectPlayer(float restore_percent, bool applySickness=false)
Definition: Player.cpp:4459
bool IsInFlight() const
Definition: Unit.h:1108
Definition: ObjectMgr.h:410
float target_Z
Definition: ObjectMgr.h:414
float target_X
Definition: ObjectMgr.h:412
float target_Orientation
Definition: ObjectMgr.h:415
float target_Y
Definition: ObjectMgr.h:413
uint32 target_mapId
Definition: ObjectMgr.h:411
Definition: ObjectMgr.h:419
uint32 entry
Definition: ObjectMgr.h:420
uint32 map
Definition: ObjectMgr.h:421
bool IsDungeon() const
Definition: Map.h:448
EnterState
Definition: Map.h:423
@ CANNOT_ENTER_TOO_MANY_INSTANCES
Definition: Map.h:432
@ CANNOT_ENTER_MAX_PLAYERS
Definition: Map.h:433
@ CANNOT_ENTER_ZONE_IN_COMBAT
Definition: Map.h:434
@ CANNOT_ENTER_INSTANCE_BIND_MISMATCH
Definition: Map.h:431
@ CANNOT_ENTER_NOT_IN_RAID
Definition: Map.h:429
Definition: OutdoorPvP.h:186

References _player, Player::AreaExploredOrEventHappens(), Map::CANNOT_ENTER_INSTANCE_BIND_MISMATCH, Map::CANNOT_ENTER_MAX_PLAYERS, Map::CANNOT_ENTER_NOT_IN_RAID, Map::CANNOT_ENTER_TOO_MANY_INSTANCES, Map::CANNOT_ENTER_ZONE_IN_COMBAT, AreaTrigger::entry, FACTION_MASK_ALLIANCE, FACTION_MASK_HORDE, Player::GetBattleground(), Player::GetCorpseLocation(), Player::GetGroup(), Object::GetGUID(), WorldObject::GetMap(), WorldLocation::GetMapId(), WorldObject::GetName(), Player::GetOutdoorPvP(), GetPlayer(), Player::GetQuestStatus(), Player::GetTeamId(), Object::HasByteFlag(), Player::HasCorpse(), Unit::IsAlive(), Player::isDebugAreaTriggers, Map::IsDungeon(), Player::IsInAreaTriggerRadius(), Unit::IsInFlight(), LANG_DEBUG_AREATRIGGER_REACHED, LOG_DEBUG, AreaTrigger::map, ChatHandler::PSendSysMessage(), QUEST_STATUS_INCOMPLETE, Object::RemoveByteFlag(), REST_FLAG_IN_TAVERN, Player::ResurrectPlayer(), Player::SetRestFlag(), sMapMgr, sObjectMgr, Player::SpawnCorpseBones(), sScriptMgr, STATUS_IN_PROGRESS, sWorld, AreaTriggerTeleport::target_mapId, AreaTriggerTeleport::target_Orientation, AreaTriggerTeleport::target_X, AreaTriggerTeleport::target_Y, AreaTriggerTeleport::target_Z, TEAM_ALLIANCE, TELE_TO_NOT_LEAVE_TRANSPORT, Player::TeleportTo(), Player::TeleportToEntryPoint(), ObjectGuid::ToString(), UNIT_BYTE2_FLAG_FFA_PVP, and UNIT_FIELD_BYTES_2.

Referenced by OpcodeTable::Initialize().

◆ HandleArenaTeamAcceptOpcode()

void WorldSession::HandleArenaTeamAcceptOpcode ( WorldPacket recvData)
169{
170 LOG_DEBUG("network", "CMSG_ARENA_TEAM_ACCEPT"); // empty opcode
171
172 ArenaTeam* arenaTeam = sArenaTeamMgr->GetArenaTeamById(_player->GetArenaTeamIdInvited());
173 if (!arenaTeam)
174 return;
175
176 // Check if player is already in another team of the same size
177 if (_player->GetArenaTeamId(arenaTeam->GetSlot()))
178 {
180 return;
181 }
182
183 // Only allow members of the other faction to join the team if cross faction interaction is enabled
184 if (!sWorld->getBoolConfig(CONFIG_ALLOW_TWO_SIDE_INTERACTION_ARENA) && _player->GetTeamId() != sCharacterCache->GetCharacterTeamByGuid(arenaTeam->GetCaptain()))
185 {
187 return;
188 }
189
190 // Add player to team
191 if (!arenaTeam->AddMember(_player->GetGUID()))
192 {
194 return;
195 }
196
197 // Broadcast event
198 arenaTeam->BroadcastEvent(ERR_ARENA_TEAM_JOIN_SS, _player->GetGUID(), 2, _player->GetName().c_str(), arenaTeam->GetName(), "");
199}
#define sArenaTeamMgr
Definition: ArenaTeamMgr.h:67
@ ERR_ARENA_TEAM_CREATE_S
Definition: ArenaTeam.h:32
@ ERR_ARENA_TEAM_INTERNAL
Definition: ArenaTeam.h:40
@ ERR_ALREADY_IN_ARENA_TEAM
Definition: ArenaTeam.h:41
@ ERR_ARENA_TEAM_NOT_ALLIED
Definition: ArenaTeam.h:52
@ ERR_ARENA_TEAM_JOIN_SS
Definition: ArenaTeam.h:63
@ CONFIG_ALLOW_TWO_SIDE_INTERACTION_ARENA
Definition: IWorld.h:77
Definition: ArenaTeam.h:137
ObjectGuid GetCaptain() const
Definition: ArenaTeam.h:153
uint8 GetSlot() const
Definition: ArenaTeam.h:150
void BroadcastEvent(ArenaTeamEvents event, ObjectGuid guid, uint8 strCount, std::string const &str1, std::string const &str2, std::string const &str3)
Definition: ArenaTeam.cpp:570
bool AddMember(ObjectGuid playerGuid)
Definition: ArenaTeam.cpp:89
std::string const & GetName() const
Definition: ArenaTeam.h:154
uint32 GetArenaTeamId(uint8 slot) const
Definition: Player.cpp:16215
uint32 GetArenaTeamIdInvited()
Definition: Player.h:1900
void SendArenaTeamCommandResult(uint32 team_action, std::string const &team, std::string const &player, uint32 error_id=0)
Definition: ArenaTeamHandler.cpp:406

References _player, ArenaTeam::AddMember(), ArenaTeam::BroadcastEvent(), CONFIG_ALLOW_TWO_SIDE_INTERACTION_ARENA, ERR_ALREADY_IN_ARENA_TEAM, ERR_ARENA_TEAM_CREATE_S, ERR_ARENA_TEAM_INTERNAL, ERR_ARENA_TEAM_JOIN_SS, ERR_ARENA_TEAM_NOT_ALLIED, Player::GetArenaTeamId(), Player::GetArenaTeamIdInvited(), ArenaTeam::GetCaptain(), Object::GetGUID(), ArenaTeam::GetName(), WorldObject::GetName(), ArenaTeam::GetSlot(), Player::GetTeamId(), LOG_DEBUG, sArenaTeamMgr, sCharacterCache, SendArenaTeamCommandResult(), and sWorld.

Referenced by OpcodeTable::Initialize().

◆ HandleArenaTeamDeclineOpcode()

void WorldSession::HandleArenaTeamDeclineOpcode ( WorldPacket recvData)
202{
203 LOG_DEBUG("network", "CMSG_ARENA_TEAM_DECLINE"); // empty opcode
204
205 // Remove invite from player
207}
void SetArenaTeamIdInvited(uint32 ArenaTeamId)
Definition: Player.h:1899

References _player, LOG_DEBUG, and Player::SetArenaTeamIdInvited().

Referenced by OpcodeTable::Initialize().

◆ HandleArenaTeamDisbandOpcode()

void WorldSession::HandleArenaTeamDisbandOpcode ( WorldPacket recvData)
267{
268 LOG_DEBUG("network", "CMSG_ARENA_TEAM_DISBAND");
269
270 uint32 arenaTeamId;
271 recvData >> arenaTeamId;
272
273 if (ArenaTeam* arenaTeam = sArenaTeamMgr->GetArenaTeamById(arenaTeamId))
274 {
275 // Only captain can disband the team
276 if (arenaTeam->GetCaptain() != _player->GetGUID())
277 return;
278
279 // Teams cannot be disbanded during queues
281 {
282 GroupQueueInfo ginfo;
283 BattlegroundQueue& queue = sBattlegroundMgr->GetBattlegroundQueue(bgQueue);
284 if (queue.GetPlayerGroupInfoData(_player->GetGUID(), &ginfo))
286 return;
287 }
288
289 // Teams cannot be disbanded during fights
290 if (arenaTeam->IsFighting())
291 return;
292
293 arenaTeam->Disband(this);
294 delete arenaTeam;
295 }
296}
@ BATTLEGROUND_AA
Definition: SharedDefines.h:3486
BattlegroundQueueTypeId
Definition: SharedDefines.h:3619
static BattlegroundQueueTypeId BGQueueTypeId(BattlegroundTypeId bgTypeId, uint8 arenaType)
Definition: BattlegroundMgr.cpp:672
Definition: BattlegroundQueue.h:31
uint32 IsInvitedToBGInstanceGUID
Definition: BattlegroundQueue.h:41
Definition: BattlegroundQueue.h:64
bool GetPlayerGroupInfoData(ObjectGuid guid, GroupQueueInfo *ginfo)
Definition: BattlegroundQueue.cpp:385

References _player, BATTLEGROUND_AA, BattlegroundMgr::BGQueueTypeId(), Object::GetGUID(), BattlegroundQueue::GetPlayerGroupInfoData(), GroupQueueInfo::IsInvitedToBGInstanceGUID, LOG_DEBUG, sArenaTeamMgr, and sBattlegroundMgr.

Referenced by OpcodeTable::Initialize().

◆ HandleArenaTeamInviteOpcode()

void WorldSession::HandleArenaTeamInviteOpcode ( WorldPacket recvData)
85{
86 LOG_DEBUG("network", "CMSG_ARENA_TEAM_INVITE");
87
88 uint32 arenaTeamId; // arena team id
89 std::string invitedName;
90
91 Player* player = nullptr;
92
93 recvData >> arenaTeamId >> invitedName;
94
95 if (!invitedName.empty())
96 {
97 if (!normalizePlayerName(invitedName))
98 return;
99
100 player = ObjectAccessor::FindPlayerByName(invitedName, false);
101 }
102
103 if (!player)
104 {
106 return;
107 }
108
109 if (player->GetLevel() < sWorld->getIntConfig(CONFIG_MAX_PLAYER_LEVEL))
110 {
112 return;
113 }
114
115 ArenaTeam* arenaTeam = sArenaTeamMgr->GetArenaTeamById(arenaTeamId);
116 if (!arenaTeam)
117 {
119 return;
120 }
121
122 if (GetPlayer()->GetArenaTeamId(arenaTeam->GetSlot()) != arenaTeamId)
123 {
125 return;
126 }
127
128 // OK result but don't send invite
129 if (player->GetSocial()->HasIgnore(GetPlayer()->GetGUID()))
130 return;
131
132 if (!sWorld->getBoolConfig(CONFIG_ALLOW_TWO_SIDE_INTERACTION_ARENA) && player->GetTeamId() != GetPlayer()->GetTeamId())
133 {
135 return;
136 }
137
138 if (player->GetArenaTeamId(arenaTeam->GetSlot()))
139 {
141 return;
142 }
143
144 if (player->GetArenaTeamIdInvited())
145 {
147 return;
148 }
149
150 if (arenaTeam->GetMembersSize() >= arenaTeam->GetType() * 2)
151 {
153 return;
154 }
155
156 LOG_DEBUG("bg.battleground", "Player {} Invited {} to Join his ArenaTeam", GetPlayer()->GetName(), invitedName);
157
158 player->SetArenaTeamIdInvited(arenaTeam->GetId());
159
160 WorldPacket data(SMSG_ARENA_TEAM_INVITE, (8 + 10));
161 data << GetPlayer()->GetName();
162 data << arenaTeam->GetName();
163 player->GetSession()->SendPacket(&data);
164
165 LOG_DEBUG("network", "WORLD: Sent SMSG_ARENA_TEAM_INVITE");
166}
@ ERR_ARENA_TEAM_INVITE_SS
Definition: ArenaTeam.h:33
@ ERR_ARENA_TEAM_TOO_MANY_MEMBERS_S
Definition: ArenaTeam.h:56
@ ERR_ALREADY_IN_ARENA_TEAM_S
Definition: ArenaTeam.h:42
@ ERR_ARENA_TEAM_PLAYER_NOT_IN_TEAM
Definition: ArenaTeam.h:49
@ ERR_ARENA_TEAM_PERMISSIONS
Definition: ArenaTeam.h:48
@ ERR_ARENA_TEAM_TARGET_TOO_LOW_S
Definition: ArenaTeam.h:54
@ ERR_ARENA_TEAM_PLAYER_NOT_FOUND_S
Definition: ArenaTeam.h:51
@ ERR_ALREADY_INVITED_TO_ARENA_TEAM_S
Definition: ArenaTeam.h:44
@ CONFIG_MAX_PLAYER_LEVEL
Definition: IWorld.h:235
@ SMSG_ARENA_TEAM_INVITE
Definition: Opcodes.h:878
Player * FindPlayerByName(std::string const &name, bool checkInWorld=true)
Definition: ObjectAccessor.cpp:271
std::size_t GetMembersSize() const
Definition: ArenaTeam.h:169
uint32 GetType() const
Definition: ArenaTeam.h:149
uint32 GetId() const
Definition: ArenaTeam.h:148
bool HasIgnore(ObjectGuid ignore_guid) const
Definition: SocialMgr.cpp:193

References CONFIG_ALLOW_TWO_SIDE_INTERACTION_ARENA, CONFIG_MAX_PLAYER_LEVEL, ERR_ALREADY_IN_ARENA_TEAM_S, ERR_ALREADY_INVITED_TO_ARENA_TEAM_S, ERR_ARENA_TEAM_CREATE_S, ERR_ARENA_TEAM_INVITE_SS, ERR_ARENA_TEAM_NOT_ALLIED, ERR_ARENA_TEAM_PERMISSIONS, ERR_ARENA_TEAM_PLAYER_NOT_FOUND_S, ERR_ARENA_TEAM_PLAYER_NOT_IN_TEAM, ERR_ARENA_TEAM_TARGET_TOO_LOW_S, ERR_ARENA_TEAM_TOO_MANY_MEMBERS_S, ObjectAccessor::FindPlayerByName(), Player::GetArenaTeamId(), Player::GetArenaTeamIdInvited(), ArenaTeam::GetId(), Unit::GetLevel(), ArenaTeam::GetMembersSize(), ArenaTeam::GetName(), WorldObject::GetName(), GetPlayer(), Player::GetSession(), ArenaTeam::GetSlot(), Player::GetSocial(), Player::GetTeamId(), GetTeamId(), ArenaTeam::GetType(), PlayerSocial::HasIgnore(), LOG_DEBUG, normalizePlayerName(), sArenaTeamMgr, SendArenaTeamCommandResult(), SendPacket(), Player::SetArenaTeamIdInvited(), SMSG_ARENA_TEAM_INVITE, and sWorld.

Referenced by OpcodeTable::Initialize().

◆ HandleArenaTeamLeaderOpcode()

void WorldSession::HandleArenaTeamLeaderOpcode ( WorldPacket recvData)
364{
365 LOG_DEBUG("network", "CMSG_ARENA_TEAM_LEADER");
366
367 uint32 arenaTeamId;
368 std::string name;
369
370 recvData >> arenaTeamId;
371 recvData >> name;
372
373 // Check for valid arena team
374 ArenaTeam* arenaTeam = sArenaTeamMgr->GetArenaTeamById(arenaTeamId);
375 if (!arenaTeam)
376 return;
377
378 // Only captain can pass leadership
379 if (arenaTeam->GetCaptain() != _player->GetGUID())
380 {
382 return;
383 }
384
385 if (!normalizePlayerName(name))
386 return;
387
388 // Check if team member exists
389 ArenaTeamMember* member = arenaTeam->GetMember(name);
390 if (!member)
391 {
393 return;
394 }
395
396 // Check if the target is already team captain
397 if (arenaTeam->GetCaptain() == member->Guid)
398 return;
399
400 arenaTeam->SetCaptain(member->Guid);
401
402 // Broadcast event
403 arenaTeam->BroadcastEvent(ERR_ARENA_TEAM_LEADER_CHANGED_SSS, ObjectGuid::Empty, 3, _player->GetName().c_str(), name, arenaTeam->GetName());
404}
@ ERR_ARENA_TEAM_LEADER_CHANGED_SSS
Definition: ArenaTeam.h:67
Definition: ArenaTeam.h:108
ObjectGuid Guid
Definition: ArenaTeam.h:109
void SetCaptain(ObjectGuid guid)
Definition: ArenaTeam.cpp:295
ArenaTeamMember * GetMember(ObjectGuid guid)
Definition: ArenaTeam.cpp:1012

References _player, ArenaTeam::BroadcastEvent(), ObjectGuid::Empty, ERR_ARENA_TEAM_CREATE_S, ERR_ARENA_TEAM_LEADER_CHANGED_SSS, ERR_ARENA_TEAM_PERMISSIONS, ERR_ARENA_TEAM_PLAYER_NOT_FOUND_S, ArenaTeam::GetCaptain(), Object::GetGUID(), ArenaTeam::GetMember(), ArenaTeam::GetName(), WorldObject::GetName(), ArenaTeamMember::Guid, LOG_DEBUG, normalizePlayerName(), sArenaTeamMgr, SendArenaTeamCommandResult(), and ArenaTeam::SetCaptain().

Referenced by OpcodeTable::Initialize().

◆ HandleArenaTeamLeaveOpcode()

void WorldSession::HandleArenaTeamLeaveOpcode ( WorldPacket recvData)
210{
211 LOG_DEBUG("network", "CMSG_ARENA_TEAM_LEAVE");
212
213 uint32 arenaTeamId;
214 recvData >> arenaTeamId;
215
216 ArenaTeam* arenaTeam = sArenaTeamMgr->GetArenaTeamById(arenaTeamId);
217 if (!arenaTeam)
218 return;
219
220 // Disallow leave team while in arena
221 if (arenaTeam->IsFighting())
222 {
224 return;
225 }
226
227 // Team captain can't leave the team if other members are still present
228 if (_player->GetGUID() == arenaTeam->GetCaptain() && arenaTeam->GetMembersSize() > 1)
229 {
231 return;
232 }
233
234 // Player cannot be removed during queues
236 {
237 GroupQueueInfo ginfo;
238 BattlegroundQueue& queue = sBattlegroundMgr->GetBattlegroundQueue(bgQueue);
239 if (queue.GetPlayerGroupInfoData(_player->GetGUID(), &ginfo))
240 {
242 {
244 return;
245 }
246 }
247 }
248
249 // If team consists only of the captain, disband the team
250 if (_player->GetGUID() == arenaTeam->GetCaptain())
251 {
252 arenaTeam->Disband(this);
253 delete arenaTeam;
254 return;
255 }
256 else
257 arenaTeam->DelMember(_player->GetGUID(), true);
258
259 // Broadcast event
260 arenaTeam->BroadcastEvent(ERR_ARENA_TEAM_LEAVE_SS, _player->GetGUID(), 2, _player->GetName().c_str(), arenaTeam->GetName(), "");
261
262 // Inform player who left
264}
@ ERR_ARENA_TEAM_QUIT_S
Definition: ArenaTeam.h:34
@ ERR_ARENA_TEAMS_LOCKED
Definition: ArenaTeam.h:58
@ ERR_ARENA_TEAM_LEADER_LEAVE_S
Definition: ArenaTeam.h:47
@ ERR_ARENA_TEAM_LEAVE_SS
Definition: ArenaTeam.h:64
void Disband(WorldSession *session)
Definition: ArenaTeam.cpp:383
void DelMember(ObjectGuid guid, bool cleanDb)
Definition: ArenaTeam.cpp:324
bool IsFighting() const
Definition: ArenaTeam.cpp:997

References _player, BATTLEGROUND_AA, BattlegroundMgr::BGQueueTypeId(), ArenaTeam::BroadcastEvent(), ArenaTeam::DelMember(), ArenaTeam::Disband(), ERR_ARENA_TEAM_LEADER_LEAVE_S, ERR_ARENA_TEAM_LEAVE_SS, ERR_ARENA_TEAM_QUIT_S, ERR_ARENA_TEAMS_LOCKED, ArenaTeam::GetCaptain(), Object::GetGUID(), ArenaTeam::GetMembersSize(), ArenaTeam::GetName(), WorldObject::GetName(), BattlegroundQueue::GetPlayerGroupInfoData(), ArenaTeam::GetType(), ArenaTeam::IsFighting(), GroupQueueInfo::IsInvitedToBGInstanceGUID, LOG_DEBUG, sArenaTeamMgr, sBattlegroundMgr, and SendArenaTeamCommandResult().

Referenced by OpcodeTable::Initialize().

◆ HandleArenaTeamQueryOpcode()

void WorldSession::HandleArenaTeamQueryOpcode ( WorldPacket recvData)
64{
65 uint32 arenaTeamId;
66 recvData >> arenaTeamId;
67
68 if (ArenaTeam* arenaTeam = sArenaTeamMgr->GetArenaTeamById(arenaTeamId))
69 {
70 arenaTeam->Query(this);
71 arenaTeam->SendStats(this);
72 }
73}

References sArenaTeamMgr.

Referenced by OpcodeTable::Initialize().

◆ HandleArenaTeamRemoveOpcode()

void WorldSession::HandleArenaTeamRemoveOpcode ( WorldPacket recvData)
299{
300 LOG_DEBUG("network", "CMSG_ARENA_TEAM_REMOVE");
301
302 uint32 arenaTeamId;
303 std::string name;
304
305 recvData >> arenaTeamId;
306 recvData >> name;
307
308 // Check for valid arena team
309 ArenaTeam* arenaTeam = sArenaTeamMgr->GetArenaTeamById(arenaTeamId);
310 if (!arenaTeam)
311 return;
312
313 // Only captain can remove members
314 if (arenaTeam->GetCaptain() != _player->GetGUID())
315 {
317 return;
318 }
319
320 if (!normalizePlayerName(name))
321 return;
322
323 // Check if team member exists
324 ArenaTeamMember* member = arenaTeam->GetMember(name);
325 if (!member)
326 {
328 return;
329 }
330
331 // Captain cannot be removed
332 if (arenaTeam->GetCaptain() == member->Guid)
333 {
335 return;
336 }
337
338 // Team member cannot be removed during queues
340 {
341 GroupQueueInfo ginfo;
342 BattlegroundQueue& queue = sBattlegroundMgr->GetBattlegroundQueue(bgQueue);
343 if (queue.GetPlayerGroupInfoData(_player->GetGUID(), &ginfo))
344 {
346 {
348 return;
349 }
350 }
351 }
352
353 // Player cannot be removed during fights
354 if (arenaTeam->IsFighting())
355 return;
356
357 arenaTeam->DelMember(member->Guid, true);
358
359 // Broadcast event
361}
@ ERR_ARENA_TEAM_REMOVE_SSS
Definition: ArenaTeam.h:65

References _player, BATTLEGROUND_AA, BattlegroundMgr::BGQueueTypeId(), ArenaTeam::BroadcastEvent(), ArenaTeam::DelMember(), ObjectGuid::Empty, ERR_ARENA_TEAM_CREATE_S, ERR_ARENA_TEAM_LEADER_LEAVE_S, ERR_ARENA_TEAM_PERMISSIONS, ERR_ARENA_TEAM_PLAYER_NOT_FOUND_S, ERR_ARENA_TEAM_QUIT_S, ERR_ARENA_TEAM_REMOVE_SSS, ERR_ARENA_TEAMS_LOCKED, ArenaTeam::GetCaptain(), Object::GetGUID(), ArenaTeam::GetMember(), ArenaTeam::GetName(), WorldObject::GetName(), BattlegroundQueue::GetPlayerGroupInfoData(), ArenaTeam::GetType(), ArenaTeamMember::Guid, ArenaTeam::IsFighting(), GroupQueueInfo::IsInvitedToBGInstanceGUID, LOG_DEBUG, normalizePlayerName(), sArenaTeamMgr, sBattlegroundMgr, and SendArenaTeamCommandResult().

Referenced by OpcodeTable::Initialize().

◆ HandleArenaTeamRosterOpcode()

void WorldSession::HandleArenaTeamRosterOpcode ( WorldPacket recvData)
76{
77 uint32 arenaTeamId; // arena team id
78 recvData >> arenaTeamId;
79
80 if (ArenaTeam* arenaTeam = sArenaTeamMgr->GetArenaTeamById(arenaTeamId))
81 arenaTeam->Roster(this);
82}

References sArenaTeamMgr.

Referenced by OpcodeTable::Initialize().

◆ HandleAttackStopOpcode()

void WorldSession::HandleAttackStopOpcode ( WorldPacket recvPacket)
69{
71}
bool AttackStop()
Force the unit to stop attacking. This will clear UNIT_STATE_MELEE_ATTACKING, Interrupt current spell...
Definition: Unit.cpp:10372

References Unit::AttackStop(), and GetPlayer().

Referenced by OpcodeTable::Initialize().

◆ HandleAttackSwingOpcode()

void WorldSession::HandleAttackSwingOpcode ( WorldPacket recvPacket)

Client explicitly checks the following before sending CMSG_ATTACKSWING packet, so we'll place the same check here. Note that it might be possible to reuse this snippet in other places as well.

29{
30 ObjectGuid guid;
31 recvData >> guid;
32
33 LOG_DEBUG("network", "WORLD: Recvd CMSG_ATTACKSWING: {}", guid.ToString());
34
35 Unit* pEnemy = ObjectAccessor::GetUnit(*_player, guid);
36
37 if (!pEnemy)
38 {
39 // stop attack state at client
40 SendAttackStop(nullptr);
41 return;
42 }
43
44 if (!_player->IsValidAttackTarget(pEnemy))
45 {
46 // stop attack state at client
47 SendAttackStop(pEnemy);
48 return;
49 }
50
54 if (Vehicle* vehicle = _player->GetVehicle())
55 {
56 VehicleSeatEntry const* seat = vehicle->GetSeatForPassenger(_player);
57 ASSERT(seat);
59 {
60 SendAttackStop(pEnemy);
61 return;
62 }
63 }
64
65 _player->Attack(pEnemy, true);
66}
#define ASSERT
Definition: Errors.h:68
@ VEHICLE_SEAT_FLAG_CAN_ATTACK
Definition: DBCEnums.h:458
Unit * GetUnit(WorldObject const &, ObjectGuid const guid)
Definition: ObjectAccessor.cpp:199
Definition: Unit.h:630
bool Attack(Unit *victim, bool meleeAttack)
Definition: Unit.cpp:10241
bool IsValidAttackTarget(Unit const *target, SpellInfo const *bySpell=nullptr) const
Definition: Unit.cpp:13835
void SendAttackStop(Unit const *enemy)
Definition: CombatHandler.cpp:84
Definition: DBCStructure.h:2063
uint32 m_flags
Definition: DBCStructure.h:2065

References _player, ASSERT, Unit::Attack(), ObjectAccessor::GetUnit(), Unit::GetVehicle(), Unit::IsValidAttackTarget(), LOG_DEBUG, VehicleSeatEntry::m_flags, SendAttackStop(), ObjectGuid::ToString(), and VEHICLE_SEAT_FLAG_CAN_ATTACK.

Referenced by OpcodeTable::Initialize().

◆ HandleAuctionHelloOpcode()

void WorldSession::HandleAuctionHelloOpcode ( WorldPacket recvPacket)
34{
35 ObjectGuid guid; //NPC guid
36 recvData >> guid;
37
39 if (!unit)
40 {
41 LOG_DEBUG("network", "WORLD: HandleAuctionHelloOpcode - Unit ({}) not found or you can't interact with him.", guid.ToString());
42 return;
43 }
44
45 // remove fake death
46 if (GetPlayer()->HasUnitState(UNIT_STATE_DIED))
48
49 SendAuctionHello(guid, unit);
50}
@ UNIT_NPC_FLAG_AUCTIONEER
Definition: UnitDefines.h:315
@ UNIT_STATE_DIED
Definition: UnitDefines.h:149
@ SPELL_AURA_FEIGN_DEATH
Definition: SpellAuraDefines.h:129
void RemoveAurasByType(AuraType auraType, ObjectGuid casterGUID=ObjectGuid::Empty, Aura *except=nullptr, bool negative=true, bool positive=true)
Definition: Unit.cpp:5088
void SendAuctionHello(ObjectGuid guid, Creature *unit)
Definition: AuctionHouseHandler.cpp:53

References Player::GetNPCIfCanInteractWith(), GetPlayer(), LOG_DEBUG, Unit::RemoveAurasByType(), SendAuctionHello(), SPELL_AURA_FEIGN_DEATH, ObjectGuid::ToString(), UNIT_NPC_FLAG_AUCTIONEER, and UNIT_STATE_DIED.

Referenced by OpcodeTable::Initialize().

◆ HandleAuctionListBidderItems()

void WorldSession::HandleAuctionListBidderItems ( WorldPacket recvData)
596{
597 ObjectGuid guid; //NPC guid
598 uint32 listfrom; //page of auctions
599 uint32 outbiddedCount; //count of outbidded auctions
600
601 recvData >> guid;
602 recvData >> listfrom; // not used in fact (this list not have page control in client)
603 recvData >> outbiddedCount;
604 if (recvData.size() != (16 + outbiddedCount * 4))
605 {
606 LOG_ERROR("network.opcode", "Client sent bad opcode!!! with count: {} and size : {} (must be: {})", outbiddedCount, (unsigned long)recvData.size(), (16 + outbiddedCount * 4));
607 outbiddedCount = 0;
608 }
609
611 if (!creature)
612 {
613 LOG_DEBUG("network", "WORLD: HandleAuctionListBidderItems - Unit ({}) not found or you can't interact with him.", guid.ToString());
614 recvData.rfinish();
615 return;
616 }
617
618 // remove fake death
619 if (GetPlayer()->HasUnitState(UNIT_STATE_DIED))
621
622 AuctionHouseObject* auctionHouse = sAuctionMgr->GetAuctionsMap(creature->GetFaction());
623
624 WorldPacket data(SMSG_AUCTION_BIDDER_LIST_RESULT, (4 + 4 + 4) + 30000); // pussywizard: ensure there is enough memory
625 Player* player = GetPlayer();
626 data << (uint32) 0; //add 0 as count
627 uint32 count = 0;
628 uint32 totalcount = 0;
629 while (outbiddedCount > 0) //add all data, which client requires
630 {
631 --outbiddedCount;
632 uint32 outbiddedAuctionId;
633 recvData >> outbiddedAuctionId;
634 AuctionEntry* auction = auctionHouse->GetAuction(outbiddedAuctionId);
635 if (auction && auction->BuildAuctionInfo(data))
636 {
637 ++totalcount;
638 ++count;
639 }
640 }
641
642 auctionHouse->BuildListBidderItems(data, player, count, totalcount);
643 data.put<uint32>(0, count); // add count to placeholder
644 data << totalcount;
645 data << (uint32)300; //unk 2.3.0
646 SendPacket(&data);
647}
#define sAuctionMgr
Definition: AuctionHouseMgr.h:227
@ SMSG_AUCTION_BIDDER_LIST_RESULT
Definition: Opcodes.h:643
Definition: AuctionHouseMgr.h:101
bool BuildAuctionInfo(WorldPacket &data) const
Definition: AuctionHouseMgr.cpp:938
Definition: AuctionHouseMgr.h:130
void BuildListBidderItems(WorldPacket &data, Player *player, uint32 &count, uint32 &totalcount)
Definition: AuctionHouseMgr.cpp:703
AuctionEntry * GetAuction(uint32 id) const
Definition: AuctionHouseMgr.h:148
uint32 GetFaction() const
Definition: Unit.h:755
std::size_t size() const
Definition: ByteBuffer.h:444
void rfinish()
Definition: ByteBuffer.h:325

References AuctionEntry::BuildAuctionInfo(), AuctionHouseObject::BuildListBidderItems(), AuctionHouseObject::GetAuction(), Unit::GetFaction(), Player::GetNPCIfCanInteractWith(), GetPlayer(), LOG_DEBUG, LOG_ERROR, ByteBuffer::put(), Unit::RemoveAurasByType(), ByteBuffer::rfinish(), sAuctionMgr, SendPacket(), ByteBuffer::size(), SMSG_AUCTION_BIDDER_LIST_RESULT, SPELL_AURA_FEIGN_DEATH, ObjectGuid::ToString(), UNIT_NPC_FLAG_AUCTIONEER, and UNIT_STATE_DIED.

Referenced by OpcodeTable::Initialize().

◆ HandleAuctionListItems()

void WorldSession::HandleAuctionListItems ( WorldPacket recvData)
705{
706 std::string searchedname;
707 uint8 levelmin, levelmax, usable;
708 uint32 listfrom, auctionSlotID, auctionMainCategory, auctionSubCategory, quality;
709 ObjectGuid guid;
710
711 recvData >> guid;
712 recvData >> listfrom; // start, used for page control listing by 50 elements
713 recvData >> searchedname;
714
715 recvData >> levelmin >> levelmax;
716 recvData >> auctionSlotID >> auctionMainCategory >> auctionSubCategory;
717 recvData >> quality >> usable;
718
719 //recvData.read_skip<uint8>(); // pussywizard: this is the getAll option
720 uint8 getAll;
721 recvData >> getAll;
722
723 // Read sort block
724 uint8 sortOrderCount;
725 recvData >> sortOrderCount;
726 AuctionSortOrderVector sortOrder;
727 for (uint8 i = 0; i < sortOrderCount; i++)
728 {
729 uint8 sortMode;
730 uint8 isDesc;
731 recvData >> sortMode;
732 recvData >> isDesc;
733 AuctionSortInfo sortInfo;
734 sortInfo.isDesc = (isDesc == 1);
735 sortInfo.sortOrder = static_cast<AuctionSortOrder>(sortMode);
736 sortOrder.push_back(std::move(sortInfo));
737 }
738
739 // remove fake death
741 {
743 }
744
745 // pussywizard:
746 const Milliseconds delay = 2s;
749 if (diff > delay)
750 {
751 diff = delay;
752 }
753 _lastAuctionListItemsMSTime = now + delay - diff;
754 std::lock_guard<std::mutex> guard(AsyncAuctionListingMgr::GetTempLock());
755 AsyncAuctionListingMgr::GetTempList().emplace_back(delay - diff, _player->GetGUID(), guid, searchedname, listfrom, levelmin, levelmax, usable, auctionSlotID,
756 auctionMainCategory, auctionSubCategory, quality, getAll, sortOrder);
757}
Milliseconds GetMSTimeDiff(Milliseconds oldMSTime, Milliseconds newMSTime)
Definition: Timer.h:91
std::chrono::milliseconds Milliseconds
Milliseconds shorthand typedef.
Definition: Duration.h:27
AuctionSortOrder
Definition: AuctionHouseMgr.h:74
std::vector< AuctionSortInfo > AuctionSortOrderVector
Definition: AuctionHouseMgr.h:98
Milliseconds GetGameTimeMS()
Definition: GameTime.cpp:43
Definition: AuctionHouseMgr.h:91
bool isDesc
Definition: AuctionHouseMgr.h:95
AuctionSortOrder sortOrder
Definition: AuctionHouseMgr.h:94
bool HasUnitState(const uint32 f) const
Definition: Unit.h:673
static std::mutex & GetTempLock()
Definition: AsyncAuctionListing.h:73
static std::list< AuctionListItemsDelayEvent > & GetTempList()
Definition: AsyncAuctionListing.h:72

References _lastAuctionListItemsMSTime, _player, GameTime::GetGameTimeMS(), Object::GetGUID(), GetMSTimeDiff(), AsyncAuctionListingMgr::GetTempList(), AsyncAuctionListingMgr::GetTempLock(), Unit::HasUnitState(), AuctionSortInfo::isDesc, Unit::RemoveAurasByType(), AuctionSortInfo::sortOrder, SPELL_AURA_FEIGN_DEATH, and UNIT_STATE_DIED.

Referenced by OpcodeTable::Initialize().

◆ HandleAuctionListOwnerItems()

void WorldSession::HandleAuctionListOwnerItems ( WorldPacket recvData)
651{
652 // prevent crash caused by malformed packet
653 ObjectGuid guid;
654 uint32 listfrom;
655
656 recvData >> guid;
657 recvData >> listfrom; // not used in fact (this list does not have page control in client)
658
659 // pussywizard:
661 if (_lastAuctionListOwnerItemsMSTime > now) // list is pending
662 return;
663
664 const Milliseconds delay = Milliseconds(4500);
666 if (diff > delay)
667 diff = delay;
668
669 _lastAuctionListOwnerItemsMSTime = now + delay; // set longest possible here, actual executing will change this to getMSTime of that moment
671}
void AddEvent(BasicEvent *Event, uint64 e_time, bool set_addtime=true)
Definition: EventProcessor.h:103
uint64 CalculateTime(uint64 t_offset) const
Definition: EventProcessor.cpp:159
EventProcessor m_Events
Definition: Unit.h:1809
Definition: AsyncAuctionListing.h:26

References _lastAuctionListOwnerItemsMSTime, _player, EventProcessor::AddEvent(), EventProcessor::CalculateTime(), GameTime::GetGameTimeMS(), Object::GetGUID(), GetMSTimeDiff(), and Unit::m_Events.

Referenced by OpcodeTable::Initialize().

◆ HandleAuctionListOwnerItemsEvent()

void WorldSession::HandleAuctionListOwnerItemsEvent ( ObjectGuid  creatureGuid)
674{
676
678 if (!creature)
679 {
680 LOG_DEBUG("network", "WORLD: HandleAuctionListOwnerItems - Unit ({}) not found or you can't interact with him.", creatureGuid.ToString());
681 return;
682 }
683
684 // remove fake death
685 if (GetPlayer()->HasUnitState(UNIT_STATE_DIED))
687
688 AuctionHouseObject* auctionHouse = sAuctionMgr->GetAuctionsMap(creature->GetFaction());
689
690 WorldPacket data(SMSG_AUCTION_OWNER_LIST_RESULT, (4 + 4 + 4) + 60000); // pussywizard: ensure there is enough memory
691 data << (uint32) 0; // amount place holder
692
693 uint32 count = 0;
694 uint32 totalcount = 0;
695
696 auctionHouse->BuildListOwnerItems(data, _player, count, totalcount);
697 data.put<uint32>(0, count);
698 data << (uint32) totalcount;
699 data << (uint32) 0;
700 SendPacket(&data);
701}
@ SMSG_AUCTION_OWNER_LIST_RESULT
Definition: Opcodes.h:635
void BuildListOwnerItems(WorldPacket &data, Player *player, uint32 &count, uint32 &totalcount)
Definition: AuctionHouseMgr.cpp:718

References _lastAuctionListOwnerItemsMSTime, _player, AuctionHouseObject::BuildListOwnerItems(), Unit::GetFaction(), GameTime::GetGameTimeMS(), Player::GetNPCIfCanInteractWith(), GetPlayer(), LOG_DEBUG, ByteBuffer::put(), Unit::RemoveAurasByType(), sAuctionMgr, SendPacket(), SMSG_AUCTION_OWNER_LIST_RESULT, SPELL_AURA_FEIGN_DEATH, ObjectGuid::ToString(), UNIT_NPC_FLAG_AUCTIONEER, and UNIT_STATE_DIED.

◆ HandleAuctionListPendingSales()

void WorldSession::HandleAuctionListPendingSales ( WorldPacket recvData)
760{
761 recvData.read_skip<uint64>();
762
763 uint32 count = 0;
764
766 data << uint32(count); // count
767 /*for (uint32 i = 0; i < count; ++i)
768 {
769 data << ""; // string
770 data << ""; // string
771 data << uint32(0);
772 data << uint32(0);
773 data << float(0);
774 }*/
775 SendPacket(&data);
776}
@ SMSG_AUCTION_LIST_PENDING_SALES
Definition: Opcodes.h:1198
void read_skip()
Definition: ByteBuffer.h:339

References ByteBuffer::read_skip(), SendPacket(), and SMSG_AUCTION_LIST_PENDING_SALES.

Referenced by OpcodeTable::Initialize().

◆ HandleAuctionPlaceBid()

void WorldSession::HandleAuctionPlaceBid ( WorldPacket recvData)
392{
393 ObjectGuid auctioneer;
394 uint32 auctionId;
395 uint32 price;
396 recvData >> auctioneer;
397 recvData >> auctionId >> price;
398
399 if (!auctionId || !price)
400 return; //check for cheaters
401
403 if (!creature)
404 {
405 LOG_DEBUG("network", "WORLD: HandleAuctionPlaceBid - Unit ({}) not found or you can't interact with him.", auctioneer.ToString());
406 return;
407 }
408
409 // remove fake death
410 if (GetPlayer()->HasUnitState(UNIT_STATE_DIED))
412
413 AuctionHouseObject* auctionHouse = sAuctionMgr->GetAuctionsMap(creature->GetFaction());
414
415 AuctionEntry* auction = auctionHouse->GetAuction(auctionId);
416 Player* player = GetPlayer();
417
418 if (!sScriptMgr->CanPlaceAuctionBid(player, auction))
419 {
421 return;
422 }
423
424 if (!auction || auction->owner == player->GetGUID())
425 {
426 //you cannot bid your own auction:
428 return;
429 }
430
431 // impossible have online own another character (use this for speedup check in case online owner)
432 Player* auction_owner = ObjectAccessor::FindConnectedPlayer(auction->owner);
433 if (!auction_owner && sCharacterCache->GetCharacterAccountIdByGuid(auction->owner) == GetAccountId())
434 {
435 //you cannot bid your another character auction:
437 return;
438 }
439
440 // cheating
441 if (price <= auction->bid || price < auction->startbid)
442 return;
443
444 // price too low for next bid if not buyout
445 if ((price < auction->buyout || auction->buyout == 0) &&
446 price < auction->bid + auction->GetAuctionOutBid())
447 {
448 //auction has already higher bid, client tests it!
449 return;
450 }
451
452 if (!player->HasEnoughMoney(price))
453 {
454 //you don't have enought money!, client tests!
455 //SendAuctionCommandResult(auction->auctionId, AUCTION_PLACE_BID, ???);
456 return;
457 }
458
459 CharacterDatabaseTransaction trans = CharacterDatabase.BeginTransaction();
460
461 if (price < auction->buyout || auction->buyout == 0)
462 {
463 if (auction->bidder)
464 {
465 if (auction->bidder == player->GetGUID())
466 player->ModifyMoney(-int32(price - auction->bid));
467 else
468 {
469 // mail to last bidder and return money
470 sAuctionMgr->SendAuctionOutbiddedMail(auction, price, GetPlayer(), trans);
471 player->ModifyMoney(-int32(price));
472 }
473 }
474 else
475 player->ModifyMoney(-int32(price));
476
477 auction->bidder = player->GetGUID();
478 auction->bid = price;
480
482 stmt->SetData(0, auction->bidder.GetCounter());
483 stmt->SetData(1, auction->bid);
484 stmt->SetData(2, auction->Id);
485 trans->Append(stmt);
486
488 }
489 else
490 {
491 //buyout:
492 if (player->GetGUID() == auction->bidder)
493 player->ModifyMoney(-int32(auction->buyout - auction->bid));
494 else
495 {
496 player->ModifyMoney(-int32(auction->buyout));
497 if (auction->bidder) //buyout for bidded auction ..
498 sAuctionMgr->SendAuctionOutbiddedMail(auction, auction->buyout, GetPlayer(), trans);
499 }
500 auction->bidder = player->GetGUID();
501 auction->bid = auction->buyout;
503
504 //- Mails must be under transaction control too to prevent data loss
505 sAuctionMgr->SendAuctionSalePendingMail(auction, trans);
506 sAuctionMgr->SendAuctionSuccessfulMail(auction, trans);
507 sAuctionMgr->SendAuctionWonMail(auction, trans);
508 sScriptMgr->OnAuctionSuccessful(auctionHouse, auction);
509
511
512 auction->DeleteFromDB(trans);
513
514 sAuctionMgr->RemoveAItem(auction->item_guid);
515 auctionHouse->RemoveAuction(auction);
516 }
517 player->SaveInventoryAndGoldToDB(trans);
518 CharacterDatabase.CommitTransaction(trans);
519}
@ AUCTION_PLACE_BID
Definition: AuctionHouseMgr.h:52
@ ERR_AUCTION_OK
Definition: AuctionHouseMgr.h:37
@ ERR_AUCTION_RESTRICTED_ACCOUNT
Definition: AuctionHouseMgr.h:45
@ ERR_AUCTION_BID_OWN
Definition: AuctionHouseMgr.h:44
@ CHAR_UPD_AUCTION_BID
Definition: CharacterDatabase.h:107
@ ACHIEVEMENT_CRITERIA_TYPE_HIGHEST_AUCTION_BID
Definition: DBCEnums.h:191
Definition: PreparedStatement.h:157
Acore::Types::is_default< T > SetData(const uint8 index, T value)
Definition: PreparedStatement.h:77
uint32 GetAuctionOutBid() const
the sum of outbid is (1% from current bid)*5, if bid is very small, it is 1c
Definition: AuctionHouseMgr.cpp:979
uint32 bid
Definition: AuctionHouseMgr.h:109
void DeleteFromDB(CharacterDatabaseTransaction trans) const
Definition: AuctionHouseMgr.cpp:985
ObjectGuid bidder
Definition: AuctionHouseMgr.h:112
ObjectGuid item_guid
Definition: AuctionHouseMgr.h:104
uint32 Id
Definition: AuctionHouseMgr.h:102
uint32 buyout
Definition: AuctionHouseMgr.h:110
ObjectGuid owner
Definition: AuctionHouseMgr.h:107
bool RemoveAuction(AuctionEntry *auction)
Definition: AuctionHouseMgr.cpp:645
void SendAuctionCommandResult(uint32 auctionId, uint32 Action, uint32 ErrorCode, uint32 bidError=0)
Definition: AuctionHouseHandler.cpp:76

References ACHIEVEMENT_CRITERIA_TYPE_HIGHEST_AUCTION_BID, AUCTION_PLACE_BID, AuctionEntry::bid, AuctionEntry::bidder, AuctionEntry::buyout, CHAR_UPD_AUCTION_BID, CharacterDatabase, AuctionEntry::DeleteFromDB(), ERR_AUCTION_BID_OWN, ERR_AUCTION_OK, ERR_AUCTION_RESTRICTED_ACCOUNT, ObjectAccessor::FindConnectedPlayer(), GetAccountId(), AuctionHouseObject::GetAuction(), AuctionEntry::GetAuctionOutBid(), ObjectGuid::GetCounter(), Unit::GetFaction(), Object::GetGUID(), Player::GetNPCIfCanInteractWith(), GetPlayer(), Player::HasEnoughMoney(), AuctionEntry::Id, AuctionEntry::item_guid, LOG_DEBUG, Player::ModifyMoney(), AuctionEntry::owner, AuctionHouseObject::RemoveAuction(), Unit::RemoveAurasByType(), sAuctionMgr, Player::SaveInventoryAndGoldToDB(), sCharacterCache, SendAuctionCommandResult(), PreparedStatementBase::SetData(), SPELL_AURA_FEIGN_DEATH, sScriptMgr, ObjectGuid::ToString(), UNIT_NPC_FLAG_AUCTIONEER, UNIT_STATE_DIED, and Player::UpdateAchievementCriteria().

Referenced by OpcodeTable::Initialize().

◆ HandleAuctionRemoveItem()

void WorldSession::HandleAuctionRemoveItem ( WorldPacket recvData)
523{
524 ObjectGuid auctioneer;
525 uint32 auctionId;
526 recvData >> auctioneer;
527 recvData >> auctionId;
528
530 if (!creature)
531 {
532 LOG_DEBUG("network", "WORLD: HandleAuctionRemoveItem - Unit ({}) not found or you can't interact with him.", auctioneer.ToString());
533 return;
534 }
535
536 // remove fake death
537 if (GetPlayer()->HasUnitState(UNIT_STATE_DIED))
539
540 AuctionHouseObject* auctionHouse = sAuctionMgr->GetAuctionsMap(creature->GetFaction());
541
542 AuctionEntry* auction = auctionHouse->GetAuction(auctionId);
543 Player* player = GetPlayer();
544
545 CharacterDatabaseTransaction trans = CharacterDatabase.BeginTransaction();
546 if (auction && auction->owner == player->GetGUID())
547 {
548 Item* pItem = sAuctionMgr->GetAItem(auction->item_guid);
549 if (pItem)
550 {
551 if (auction->bidder) // If we have a bidder, we have to send him the money he paid
552 {
553 uint32 auctionCut = auction->GetAuctionCut();
554 if (!player->HasEnoughMoney(auctionCut)) //player doesn't have enough money, maybe message needed
555 return;
556 //some auctionBidderNotification would be needed, but don't know that parts..
557 sAuctionMgr->SendAuctionCancelledToBidderMail(auction, trans);
558 player->ModifyMoney(-int32(auctionCut));
559 }
560
561 // item will deleted or added to received mail list
563 .AddItem(pItem)
564 .SendMailTo(trans, player, auction, MAIL_CHECK_MASK_COPIED);
565 }
566 else
567 {
568 LOG_ERROR("network.opcode", "Auction id: {} has non-existed item (item: {})!!!", auction->Id, auction->item_guid.ToString());
570 return;
571 }
572 }
573 else
574 {
576 //this code isn't possible ... maybe there should be assert
577 LOG_ERROR("network.opcode", "CHEATER : {}, he tried to cancel auction (id: {}) of another player, or auction is nullptr", player->GetGUID().ToString(), auctionId);
578 return;
579 }
580
581 //inform player, that auction is removed
583
584 // Now remove the auction
585
586 player->SaveInventoryAndGoldToDB(trans);
587 auction->DeleteFromDB(trans);
588 CharacterDatabase.CommitTransaction(trans);
589
590 sAuctionMgr->RemoveAItem(auction->item_guid);
591 auctionHouse->RemoveAuction(auction);
592}
@ AUCTION_CANCELED
Definition: AuctionHouseMgr.h:62
@ AUCTION_CANCEL
Definition: AuctionHouseMgr.h:51
@ ERR_AUCTION_DATABASE_ERROR
Definition: AuctionHouseMgr.h:39
@ MAIL_CHECK_MASK_COPIED
This mail was returned. Do not allow returning mail back again.
Definition: Mail.h:50
static std::string BuildAuctionMailBody(ObjectGuid guid, uint32 bid, uint32 buyout, uint32 deposit=0, uint32 cut=0, uint32 moneyDelay=0, uint32 eta=0)
Definition: AuctionHouseMgr.cpp:1047
std::string BuildAuctionMailSubject(MailAuctionAnswers response) const
Definition: AuctionHouseMgr.cpp:1040
uint32 deposit
Definition: AuctionHouseMgr.h:113
uint32 GetAuctionCut() const
Definition: AuctionHouseMgr.cpp:972
Definition: Mail.h:120
void SendMailTo(CharacterDatabaseTransaction trans, MailReceiver const &receiver, MailSender const &sender, MailCheckMask checked=MAIL_CHECK_MASK_NONE, uint32 deliver_delay=0, uint32 custom_expiration=0, bool deleteMailItemsFromDB=false, bool sendMail=true)
Definition: Mail.cpp:186
MailDraft & AddItem(Item *item)
Definition: Mail.cpp:94

References MailDraft::AddItem(), AUCTION_CANCEL, AUCTION_CANCELED, AuctionEntry::bidder, AuctionEntry::BuildAuctionMailBody(), AuctionEntry::BuildAuctionMailSubject(), AuctionEntry::buyout, CharacterDatabase, AuctionEntry::DeleteFromDB(), AuctionEntry::deposit, ObjectGuid::Empty, ERR_AUCTION_DATABASE_ERROR, ERR_AUCTION_OK, AuctionHouseObject::GetAuction(), AuctionEntry::GetAuctionCut(), Unit::GetFaction(), Object::GetGUID(), Player::GetNPCIfCanInteractWith(), GetPlayer(), Player::HasEnoughMoney(), AuctionEntry::Id, AuctionEntry::item_guid, LOG_DEBUG, LOG_ERROR, MAIL_CHECK_MASK_COPIED, Player::ModifyMoney(), AuctionEntry::owner, AuctionHouseObject::RemoveAuction(), Unit::RemoveAurasByType(), sAuctionMgr, Player::SaveInventoryAndGoldToDB(), SendAuctionCommandResult(), MailDraft::SendMailTo(), SPELL_AURA_FEIGN_DEATH, ObjectGuid::ToString(), UNIT_NPC_FLAG_AUCTIONEER, and UNIT_STATE_DIED.

Referenced by OpcodeTable::Initialize().

◆ HandleAuctionSellItem()

void WorldSession::HandleAuctionSellItem ( WorldPacket recvData)
117{
118 ObjectGuid auctioneer;
119 uint32 itemsCount, etime, bid, buyout;
120 recvData >> auctioneer;
121 recvData >> itemsCount;
122
123 ObjectGuid itemGUIDs[MAX_AUCTION_ITEMS]; // 160 slot = 4x 36 slot bag + backpack 16 slot
125 memset(count, 0, sizeof(count));
126
127 if (itemsCount > MAX_AUCTION_ITEMS)
128 {
130 recvData.rfinish();
131 return;
132 }
133
134 for (uint32 i = 0; i < itemsCount; ++i)
135 {
136 recvData >> itemGUIDs[i];
137 recvData >> count[i];
138
139 if (!itemGUIDs[i] || !count[i] || count[i] > 1000)
140 {
141 recvData.rfinish();
142 return;
143 }
144 }
145
146 recvData >> bid;
147 recvData >> buyout;
148 recvData >> etime;
149
150 if (!bid || !etime)
151 return;
152
153 if (bid > MAX_MONEY_AMOUNT || buyout > MAX_MONEY_AMOUNT)
154 {
155 LOG_DEBUG("network", "WORLD: HandleAuctionSellItem - Player {} ({}) attempted to sell item with higher price than max gold amount.",
158 return;
159 }
160
162 if (!creature)
163 {
164 LOG_DEBUG("network", "WORLD: HandleAuctionSellItem - Unit ({}) not found or you can't interact with him.", auctioneer.ToString());
165 return;
166 }
167
168 AuctionHouseEntry const* auctionHouseEntry = AuctionHouseMgr::GetAuctionHouseEntry(creature->GetFaction());
169 if (!auctionHouseEntry)
170 {
171 LOG_DEBUG("network", "WORLD: HandleAuctionSellItem - Unit ({}) has wrong faction.", auctioneer.ToString());
172 return;
173 }
174
175 etime *= MINUTE;
176
177 switch (etime)
178 {
179 case 1*MIN_AUCTION_TIME:
180 case 2*MIN_AUCTION_TIME:
181 case 4*MIN_AUCTION_TIME:
182 break;
183 default:
184 return;
185 }
186
187 if (GetPlayer()->HasUnitState(UNIT_STATE_DIED))
189
190 Item* items[MAX_AUCTION_ITEMS];
191
192 uint32 finalCount = 0;
193 uint32 itemEntry = 0;
194
195 for (uint32 i = 0; i < itemsCount; ++i)
196 {
197 Item* item = _player->GetItemByGuid(itemGUIDs[i]);
198
199 if (!item)
200 {
202 return;
203 }
204
205 if (itemEntry == 0)
206 itemEntry = item->GetTemplate()->ItemId;
207
208 if (sAuctionMgr->GetAItem(item->GetGUID()) || !item->CanBeTraded() || item->IsNotEmptyBag() ||
210 item->GetCount() < count[i] || itemEntry != item->GetTemplate()->ItemId)
211 {
213 return;
214 }
215
216 items[i] = item;
217 finalCount += count[i];
218 }
219
220 if (!finalCount)
221 {
223 return;
224 }
225
226 // check if there are 2 identical guids, in this case user is most likely cheating
227 for (uint32 i = 0; i < itemsCount - 1; ++i)
228 {
229 for (uint32 j = i + 1; j < itemsCount; ++j)
230 {
231 if (itemGUIDs[i] == itemGUIDs[j])
232 {
234 return;
235 }
236 }
237 }
238
239 for (uint32 i = 0; i < itemsCount; ++i)
240 {
241 Item* item = items[i];
242
243 if (item->GetMaxStackCount() < finalCount)
244 {
246 return;
247 }
248 }
249
250 for (uint32 i = 0; i < itemsCount; ++i)
251 {
252 Item* item = items[i];
253
254 uint32 auctionTime = uint32(etime * sWorld->getRate(RATE_AUCTION_TIME));
255 AuctionHouseObject* auctionHouse = sAuctionMgr->GetAuctionsMap(creature->GetFaction());
256
257 uint32 deposit = sAuctionMgr->GetAuctionDeposit(auctionHouseEntry, etime, item, finalCount);
258 if (!_player->HasEnoughMoney(deposit))
259 {
261 return;
262 }
263
264 _player->ModifyMoney(-int32(deposit));
265
266 AuctionEntry* AH = new AuctionEntry;
267 AH->Id = sObjectMgr->GenerateAuctionID();
268
271 else
272 {
273 CreatureData const* auctioneerData = sObjectMgr->GetCreatureData(creature->GetSpawnId());
274 if (!auctioneerData)
275 {
276 LOG_ERROR("network.opcode", "Data for auctioneer not found ({})", auctioneer.ToString());
277 return;
278 }
279
280 CreatureTemplate const* auctioneerInfo = sObjectMgr->GetCreatureTemplate(auctioneerData->id1);
281 if (!auctioneerInfo)
282 {
283 LOG_ERROR("network.opcode", "Non existing auctioneer ({})", auctioneer.ToString());
284 return;
285 }
286
287 const AuctionHouseEntry* AHEntry = sAuctionMgr->GetAuctionHouseEntry(auctioneerInfo->faction);
288 AH->houseId = AHEntry->houseId;
289 }
290
291 // Required stack size of auction matches to current item stack size, just move item to auctionhouse
292 if (itemsCount == 1 && item->GetCount() == count[i])
293 {
294 AH->item_guid = item->GetGUID();
295 AH->item_template = item->GetEntry();
296 AH->itemCount = item->GetCount();
297 AH->owner = _player->GetGUID();
298 AH->startbid = bid;
300 AH->bid = 0;
301 AH->buyout = buyout;
302 AH->expire_time = GameTime::GetGameTime().count() + auctionTime;
303 AH->deposit = deposit;
304 AH->auctionHouseEntry = auctionHouseEntry;
305
306 LOG_DEBUG("network.opcode", "CMSG_AUCTION_SELL_ITEM: Player {} ({}) is selling item {} entry {} ({}) with count {} with initial bid {} with buyout {} and with time {} (in sec) in auctionhouse {}",
307 _player->GetName(), _player->GetGUID().ToString(), item->GetTemplate()->Name1, item->GetEntry(), item->GetGUID().ToString(), item->GetCount(), bid, buyout, auctionTime, AH->GetHouseId());
308 sAuctionMgr->AddAItem(item);
309 auctionHouse->AddAuction(AH);
310
311 _player->MoveItemFromInventory(item->GetBagSlot(), item->GetSlot(), true);
312
313 CharacterDatabaseTransaction trans = CharacterDatabase.BeginTransaction();
314 item->DeleteFromInventoryDB(trans);
315 item->SaveToDB(trans);
316 AH->SaveToDB(trans);
318 CharacterDatabase.CommitTransaction(trans);
319
321
323 return;
324 }
325 else // Required stack size of auction does not match to current item stack size, clone item and set correct stack size
326 {
327 Item* newItem = item->CloneItem(finalCount, _player);
328 if (!newItem)
329 {
330 LOG_ERROR("network.opcode", "CMSG_AUCTION_SELL_ITEM: Could not create clone of item {}", item->GetEntry());
332 return;
333 }
334
335 AH->item_guid = newItem->GetGUID();
336 AH->item_template = newItem->GetEntry();
337 AH->itemCount = newItem->GetCount();
338 AH->owner = _player->GetGUID();
339 AH->startbid = bid;
341 AH->bid = 0;
342 AH->buyout = buyout;
343 AH->expire_time = GameTime::GetGameTime().count() + auctionTime;
344 AH->deposit = deposit;
345 AH->auctionHouseEntry = auctionHouseEntry;
346
347 LOG_DEBUG("network.opcode", "CMSG_AUCTION_SELL_ITEM: Player {} ({}) is selling item {} entry {} ({}) with count {} with initial bid {} with buyout {} and with time {} (in sec) in auctionhouse {}",
348 _player->GetName(), _player->GetGUID().ToString(), newItem->GetTemplate()->Name1, newItem->GetEntry(), newItem->GetGUID().ToString(), newItem->GetCount(), bid, buyout, auctionTime, AH->GetHouseId());
349 sAuctionMgr->AddAItem(newItem);
350 auctionHouse->AddAuction(AH);
351
352 for (uint32 j = 0; j < itemsCount; ++j)
353 {
354 Item* item2 = items[j];
355
356 // Item stack count equals required count, ready to delete item - cloned item will be used for auction
357 if (item2->GetCount() == count[j])
358 {
359 _player->MoveItemFromInventory(item2->GetBagSlot(), item2->GetSlot(), true);
360
361 CharacterDatabaseTransaction trans = CharacterDatabase.BeginTransaction();
362 item2->DeleteFromInventoryDB(trans);
363 item2->DeleteFromDB(trans);
364 CharacterDatabase.CommitTransaction(trans);
365 delete item2;
366 }
367 else // Item stack count is bigger than required count, update item stack count and save to database - cloned item will be used for auction
368 {
369 item2->SetCount(item2->GetCount() - count[j]);
371 _player->ItemRemovedQuestCheck(item2->GetEntry(), count[j]);
373 }
374 }
375
376 CharacterDatabaseTransaction trans = CharacterDatabase.BeginTransaction();
377 newItem->SaveToDB(trans);
378 AH->SaveToDB(trans);
380 CharacterDatabase.CommitTransaction(trans);
381
383
385 return;
386 }
387 }
388}
constexpr auto MINUTE
Definition: Common.h:47
#define MIN_AUCTION_TIME
Definition: AuctionHouseMgr.h:32
@ AUCTIONHOUSE_NEUTRAL
Definition: AuctionHouseMgr.h:70
@ AUCTION_SELL_ITEM
Definition: AuctionHouseMgr.h:50
#define MAX_AUCTION_ITEMS
Definition: AuctionHouseMgr.h:33
@ ERR_AUCTION_NOT_ENOUGHT_MONEY
Definition: AuctionHouseMgr.h:40
@ ERR_AUCTION_ITEM_NOT_FOUND
Definition: AuctionHouseMgr.h:41
@ CONFIG_ALLOW_TWO_SIDE_INTERACTION_AUCTION
Definition: IWorld.h:78
@ RATE_AUCTION_TIME
Definition: IWorld.h:503
@ ITEM_FIELD_DURATION
Definition: UpdateFields.h:40
@ ITEM_FLAG_CONJURED
Definition: ItemTemplate.h:148
@ ITEM_CHANGED
Definition: Item.h:210
@ ACHIEVEMENT_CRITERIA_TYPE_CREATE_AUCTION
Definition: DBCEnums.h:190
Seconds GetGameTime()
Definition: GameTime.cpp:38
uint8 GetHouseId() const
Definition: AuctionHouseMgr.h:117
AuctionHouseEntry const * auctionHouseEntry
Definition: AuctionHouseMgr.h:114
void SaveToDB(CharacterDatabaseTransaction trans) const
Definition: AuctionHouseMgr.cpp:992
time_t expire_time
Definition: AuctionHouseMgr.h:111
uint32 startbid
Definition: AuctionHouseMgr.h:108
uint32 itemCount
Definition: AuctionHouseMgr.h:106
uint32 item_template
Definition: AuctionHouseMgr.h:105
uint8 houseId
Definition: AuctionHouseMgr.h:103
void AddAuction(AuctionEntry *auction)
Definition: AuctionHouseMgr.cpp:637
static AuctionHouseEntry const * GetAuctionHouseEntry(uint32 factionTemplateId)
Definition: AuctionHouseMgr.cpp:609
ObjectGuid::LowType GetSpawnId() const
Definition: Creature.h:68
Definition: CreatureData.h:187
uint32 faction
Definition: CreatureData.h:199
Definition: CreatureData.h:371
uint32 id1
Definition: CreatureData.h:373
static void DeleteFromInventoryDB(CharacterDatabaseTransaction trans, ObjectGuid::LowType itemGuid)
Definition: Item.cpp:533
void SetState(ItemUpdateState state, Player *forplayer=nullptr)
Definition: Item.cpp:715
virtual void SaveToDB(CharacterDatabaseTransaction trans)
Definition: Item.cpp:337
Item * CloneItem(uint32 count, Player const *player=nullptr) const
Definition: Item.cpp:1119
bool CanBeTraded(bool mail=false, bool trade=false) const
Definition: Item.cpp:795
void SetCount(uint32 value)
Definition: Item.h:273
bool IsNotEmptyBag() const
Definition: Item.cpp:312
uint32 GetMaxStackCount() const
Definition: Item.h:274
static void DeleteFromDB(CharacterDatabaseTransaction trans, ObjectGuid::LowType itemGuid)
Definition: Item.cpp:519
std::string Name1
Definition: ItemTemplate.h:624
uint32 ItemId
Definition: ItemTemplate.h:620
uint32 GetUInt32Value(uint16 index) const
Definition: Object.cpp:305
uint32 GetEntry() const
Definition: Object.h:112
void SendUpdateToPlayer(Player *player)
Definition: Object.cpp:246
void ItemRemovedQuestCheck(uint32 entry, uint32 count)
Definition: PlayerQuest.cpp:1868
Definition: DBCStructure.h:573
uint32 houseId
Definition: DBCStructure.h:574

References _player, ACHIEVEMENT_CRITERIA_TYPE_CREATE_AUCTION, AuctionHouseObject::AddAuction(), AUCTION_SELL_ITEM, AUCTIONHOUSE_NEUTRAL, AuctionEntry::auctionHouseEntry, AuctionEntry::bid, AuctionEntry::bidder, AuctionEntry::buyout, Item::CanBeTraded(), CharacterDatabase, Item::CloneItem(), CONFIG_ALLOW_TWO_SIDE_INTERACTION_AUCTION, Item::DeleteFromDB(), Item::DeleteFromInventoryDB(), AuctionEntry::deposit, ObjectGuid::Empty, ERR_AUCTION_DATABASE_ERROR, ERR_AUCTION_ITEM_NOT_FOUND, ERR_AUCTION_NOT_ENOUGHT_MONEY, ERR_AUCTION_OK, AuctionEntry::expire_time, CreatureTemplate::faction, AuctionHouseMgr::GetAuctionHouseEntry(), Item::GetBagSlot(), Item::GetCount(), Object::GetEntry(), Unit::GetFaction(), GameTime::GetGameTime(), Object::GetGUID(), AuctionEntry::GetHouseId(), Player::GetItemByGuid(), Item::GetMaxStackCount(), WorldObject::GetName(), Player::GetNPCIfCanInteractWith(), GetPlayer(), Item::GetSlot(), Creature::GetSpawnId(), Item::GetTemplate(), Object::GetUInt32Value(), Player::HasEnoughMoney(), ItemTemplate::HasFlag(), AuctionEntry::houseId, AuctionHouseEntry::houseId, AuctionEntry::Id, CreatureData::id1, Item::IsNotEmptyBag(), ITEM_CHANGED, ITEM_FIELD_DURATION, ITEM_FLAG_CONJURED, AuctionEntry::item_guid, AuctionEntry::item_template, AuctionEntry::itemCount, ItemTemplate::ItemId, Player::ItemRemovedQuestCheck(), LOG_DEBUG, LOG_ERROR, MAX_AUCTION_ITEMS, MAX_MONEY_AMOUNT, MIN_AUCTION_TIME, MINUTE, Player::ModifyMoney(), Player::MoveItemFromInventory(), ItemTemplate::Name1, AuctionEntry::owner, RATE_AUCTION_TIME, Unit::RemoveAurasByType(), ByteBuffer::rfinish(), sAuctionMgr, Player::SaveInventoryAndGoldToDB(), Item::SaveToDB(), AuctionEntry::SaveToDB(), SendAuctionCommandResult(), Object::SendUpdateToPlayer(), Item::SetCount(), Item::SetState(), sObjectMgr, SPELL_AURA_FEIGN_DEATH, AuctionEntry::startbid, sWorld, ObjectGuid::ToString(), UNIT_NPC_FLAG_AUCTIONEER, UNIT_STATE_DIED, and Player::UpdateAchievementCriteria().

Referenced by OpcodeTable::Initialize().

◆ HandleAutoBankItemOpcode()

void WorldSession::HandleAutoBankItemOpcode ( WorldPackets::Bank::AutoBankItem packet)
65{
66 LOG_DEBUG("network", "STORAGE: receive bag = {}, slot = {}", packet.Bag, packet.Slot);
67
68 if (!CanUseBank())
69 {
70 LOG_DEBUG("network", "WORLD: HandleAutoBankItemOpcode - Unit ({}) not found or you can't interact with him.", m_currentBankerGUID.ToString());
71 return;
72 }
73
74 Item* item = _player->GetItemByPos(packet.Bag, packet.Slot);
75 if (!item)
76 return;
77
78 ItemPosCountVec dest;
79 InventoryResult msg = _player->CanBankItem(NULL_BAG, NULL_SLOT, dest, item, false);
80 if (msg != EQUIP_ERR_OK)
81 {
82 _player->SendEquipError(msg, item, nullptr);
83 return;
84 }
85
86 if (dest.size() == 1 && dest[0].pos == item->GetPos())
87 {
88 _player->SendEquipError(EQUIP_ERR_NONE, item, nullptr);
89 return;
90 }
91
92 _player->RemoveItem(packet.Bag, packet.Slot, true);
94 _player->BankItem(dest, item, true);
96}
std::vector< ItemPosCount > ItemPosCountVec
Definition: Player.h:771
InventoryResult
Definition: Item.h:46
@ EQUIP_ERR_NONE
Definition: Item.h:106
@ NULL_BAG
Definition: Item.h:40
@ NULL_SLOT
Definition: Item.h:41
uint16 GetPos() const
Definition: Item.h:285
Item * BankItem(ItemPosCountVec const &dest, Item *pItem, bool update)
Definition: Player.h:1327
Item * GetItemByPos(uint16 pos) const
Definition: PlayerStorage.cpp:443
void RemoveItem(uint8 bag, uint8 slot, bool update, bool swap=false)
Definition: PlayerStorage.cpp:2901
InventoryResult CanBankItem(uint8 bag, uint8 slot, ItemPosCountVec &dest, Item *pItem, bool swap, bool not_loading=true) const
Definition: PlayerStorage.cpp:2034
void UpdateTitansGrip()
Definition: PlayerUpdates.cpp:1794
uint8 Bag
Definition: BankPackets.h:35
uint8 Slot
Definition: BankPackets.h:36
bool CanUseBank(ObjectGuid bankerGUID=ObjectGuid::Empty) const
Definition: BankHandler.cpp:26

References _player, WorldPackets::Bank::AutoBankItem::Bag, Player::BankItem(), Player::CanBankItem(), CanUseBank(), EQUIP_ERR_NONE, EQUIP_ERR_OK, Item::GetCount(), Object::GetEntry(), Player::GetItemByPos(), Item::GetPos(), Player::ItemRemovedQuestCheck(), LOG_DEBUG, m_currentBankerGUID, NULL_BAG, NULL_SLOT, Player::RemoveItem(), Player::SendEquipError(), WorldPackets::Bank::AutoBankItem::Slot, ObjectGuid::ToString(), and Player::UpdateTitansGrip().

Referenced by OpcodeTable::Initialize().

◆ HandleAutoEquipItemOpcode()

void WorldSession::HandleAutoEquipItemOpcode ( WorldPacket recvPacket)
167{
168 //LOG_DEBUG("network.opcode", "WORLD: CMSG_AUTOEQUIP_ITEM");
169 uint8 srcbag, srcslot;
170
171 recvData >> srcbag >> srcslot;
172
173 Item* pSrcItem = _player->GetItemByPos(srcbag, srcslot);
174 if (!pSrcItem)
175 return; // only at cheat
176
177 ItemTemplate const* pProto = pSrcItem->GetTemplate();
178 if (!pProto)
179 {
181 return;
182 }
183
184 uint8 eslot = _player->FindEquipSlot(pProto, NULL_SLOT, !pSrcItem->IsBag());
185 if (eslot == NULL_SLOT)
186 {
188 return;
189 }
190
191 uint16 src = pSrcItem->GetPos();
192 uint16 dest = ((INVENTORY_SLOT_BAG_0 << 8) | eslot);
193 if (dest == src) // prevent equip in same slot, only at cheat
194 {
196 return;
197 }
198
199 Item* pDstItem = _player->GetItemByPos(dest);
200
201 // Remove item enchantments for now and restore it later
202 // Needed for swap sanity checks
203 if (pDstItem)
204 {
205 _player->ApplyEnchantment(pDstItem, false);
206 }
207
208 InventoryResult msg = _player->CanEquipItem(NULL_SLOT, dest, pSrcItem, !pSrcItem->IsBag());
209 if (msg != EQUIP_ERR_OK)
210 {
211 // Restore enchantments
212 if (pDstItem)
213 {
214 _player->ApplyEnchantment(pDstItem, true);
215 }
216
217 _player->SendEquipError(msg, pSrcItem, nullptr);
218 return;
219 }
220
221 if (!pDstItem) // empty slot, simple case
222 {
223 _player->RemoveItem(srcbag, srcslot, true);
224 _player->EquipItem(dest, pSrcItem, true);
226 }
227 else // have currently equipped item, not simple case
228 {
229 // Restore enchantments
230 _player->ApplyEnchantment(pDstItem, true);
231
232 uint8 dstbag = pDstItem->GetBagSlot();
233 uint8 dstslot = pDstItem->GetSlot();
234
235 msg = _player->CanUnequipItem(dest, !pSrcItem->IsBag());
236 if (msg != EQUIP_ERR_OK)
237 {
238 _player->SendEquipError(msg, pDstItem, nullptr);
239 return;
240 }
241
242 // check dest->src move possibility
243 ItemPosCountVec sSrc;
244 uint16 eSrc = 0;
245 if (_player->IsInventoryPos(src))
246 {
247 msg = _player->CanStoreItem(srcbag, srcslot, sSrc, pDstItem, true);
248 if (msg != EQUIP_ERR_OK)
249 msg = _player->CanStoreItem(srcbag, NULL_SLOT, sSrc, pDstItem, true);
250 if (msg != EQUIP_ERR_OK)
251 msg = _player->CanStoreItem(NULL_BAG, NULL_SLOT, sSrc, pDstItem, true);
252 }
253 else if (_player->IsBankPos(src))
254 {
255 msg = _player->CanBankItem(srcbag, srcslot, sSrc, pDstItem, true);
256 if (msg != EQUIP_ERR_OK)
257 msg = _player->CanBankItem(srcbag, NULL_SLOT, sSrc, pDstItem, true);
258 if (msg != EQUIP_ERR_OK)
259 msg = _player->CanBankItem(NULL_BAG, NULL_SLOT, sSrc, pDstItem, true);
260 }
261 else if (_player->IsEquipmentPos(src))
262 {
263 msg = _player->CanEquipItem(srcslot, eSrc, pDstItem, true);
264 if (msg == EQUIP_ERR_OK)
265 msg = _player->CanUnequipItem(eSrc, true);
266 }
267
268 if (msg != EQUIP_ERR_OK)
269 {
270 _player->SendEquipError(msg, pDstItem, pSrcItem);
271 return;
272 }
273
274 // now do moves, remove...
275 _player->RemoveItem(dstbag, dstslot, true, true);
276 _player->RemoveItem(srcbag, srcslot, true, true);
277
278 // add to dest
279 _player->EquipItem(dest, pSrcItem, true);
280
281 // add to src
282 if (_player->IsInventoryPos(src))
283 _player->StoreItem(sSrc, pDstItem, true);
284 else if (_player->IsBankPos(src))
285 _player->BankItem(sSrc, pDstItem, true);
286 else if (_player->IsEquipmentPos(src))
287 _player->EquipItem(eSrc, pDstItem, true);
288
290
291 // Xinef: Call this here after all needed items are equipped
293 }
294}
#define INVENTORY_SLOT_BAG_0
Definition: Player.h:670
@ EQUIP_ERR_ITEM_CANT_BE_EQUIPPED
Definition: Item.h:67
@ EQUIP_ERR_ITEM_NOT_FOUND
Definition: Item.h:70
@ EQUIP_ERR_ITEMS_CANT_BE_SWAPPED
Definition: Item.h:68
bool IsBag() const
Definition: Item.h:254
static bool IsEquipmentPos(uint16 pos)
Definition: Player.h:1258
InventoryResult CanUnequipItem(uint16 src, bool swap) const
Definition: PlayerStorage.cpp:1986
void RemoveItemDependentAurasAndCasts(Item *pItem)
Definition: Player.cpp:12579
InventoryResult CanEquipItem(uint8 slot, uint16 &dest, Item *pItem, bool swap, bool not_loading=true) const
Definition: PlayerStorage.cpp:1807
InventoryResult CanStoreItem(uint8 bag, uint8 slot, ItemPosCountVec &dest, Item *pItem, bool swap=false) const
Definition: Player.h:1278
void ApplyEnchantment(Item *item, EnchantmentSlot slot, bool apply, bool apply_dur=true, bool ignore_condition=false)
Definition: PlayerStorage.cpp:4306
Item * StoreItem(ItemPosCountVec const &pos, Item *pItem, bool update)
Definition: PlayerStorage.cpp:2576
static bool IsInventoryPos(uint16 pos)
Definition: Player.h:1256
uint8 FindEquipSlot(ItemTemplate const *proto, uint32 slot, bool swap) const
Definition: PlayerStorage.cpp:127
void AutoUnequipOffhandIfNeed(bool force=false)
Definition: Player.cpp:12462
Item * EquipItem(uint16 pos, Item *pItem, bool update)
Definition: PlayerStorage.cpp:2729
static bool IsBankPos(uint16 pos)
Definition: Player.h:1261

References _player, Player::ApplyEnchantment(), Player::AutoUnequipOffhandIfNeed(), Player::BankItem(), Player::CanBankItem(), Player::CanEquipItem(), Player::CanStoreItem(), Player::CanUnequipItem(), EQUIP_ERR_ITEM_CANT_BE_EQUIPPED, EQUIP_ERR_ITEM_NOT_FOUND, EQUIP_ERR_ITEMS_CANT_BE_SWAPPED, EQUIP_ERR_OK, Player::EquipItem(), Player::FindEquipSlot(), Item::GetBagSlot(), Player::GetItemByPos(), Item::GetPos(), Item::GetSlot(), Item::GetTemplate(), INVENTORY_SLOT_BAG_0, Item::IsBag(), Player::IsBankPos(), Player::IsEquipmentPos(), Player::IsInventoryPos(), NULL_BAG, NULL_SLOT, Player::RemoveItem(), Player::RemoveItemDependentAurasAndCasts(), Player::SendEquipError(), and Player::StoreItem().

Referenced by OpcodeTable::Initialize().

◆ HandleAutoEquipItemSlotOpcode()

void WorldSession::HandleAutoEquipItemSlotOpcode ( WorldPacket recvPacket)
107{
108 ObjectGuid itemguid;
109 uint8 dstslot;
110 recvData >> itemguid >> dstslot;
111
112 // cheating attempt, client should never send opcode in that case
114 return;
115
116 Item* item = _player->GetItemByGuid(itemguid);
117 uint16 dstpos = dstslot | (INVENTORY_SLOT_BAG_0 << 8);
118
119 if (!item || item->GetPos() == dstpos)
120 return;
121
122 _player->SwapItem(item->GetPos(), dstpos);
123}
void SwapItem(uint16 src, uint16 dst)
Definition: PlayerStorage.cpp:3538

References _player, Player::GetItemByGuid(), Item::GetPos(), INVENTORY_SLOT_BAG_0, Player::IsEquipmentPos(), and Player::SwapItem().

Referenced by OpcodeTable::Initialize().

◆ HandleAutoStoreBagItemOpcode()

void WorldSession::HandleAutoStoreBagItemOpcode ( WorldPacket recvPacket)
1146{
1147 //LOG_DEBUG("network.opcode", "WORLD: CMSG_AUTOSTORE_BAG_ITEM");
1148 uint8 srcbag, srcslot, dstbag;
1149
1150 recvData >> srcbag >> srcslot >> dstbag;
1151
1152 Item* pItem = _player->GetItemByPos(srcbag, srcslot);
1153 if (!pItem)
1154 return;
1155
1156 if (!_player->IsValidPos(dstbag, NULL_SLOT, false)) // can be autostore pos
1157 {
1159 return;
1160 }
1161
1162 uint16 src = pItem->GetPos();
1163
1164 // check unequip potability for equipped items and bank bags
1165 if (_player->IsEquipmentPos (src) || _player->IsBagPos (src))
1166 {
1168 if (msg != EQUIP_ERR_OK)
1169 {
1170 _player->SendEquipError(msg, pItem, nullptr);
1171 return;
1172 }
1173 }
1174
1175 ItemPosCountVec dest;
1176 InventoryResult msg = _player->CanStoreItem(dstbag, NULL_SLOT, dest, pItem, false);
1177 if (msg != EQUIP_ERR_OK)
1178 {
1179 _player->SendEquipError(msg, pItem, nullptr);
1180 return;
1181 }
1182
1183 // no-op: placed in same slot
1184 if (dest.size() == 1 && dest[0].pos == src)
1185 {
1186 // just remove grey item state
1187 _player->SendEquipError(EQUIP_ERR_NONE, pItem, nullptr);
1188 return;
1189 }
1190
1191 _player->RemoveItem(srcbag, srcslot, true);
1192 _player->StoreItem(dest, pItem, true);
1194}
@ EQUIP_ERR_ITEM_DOESNT_GO_TO_SLOT
Definition: Item.h:50
static bool IsBagPos(uint16 pos)
Definition: PlayerStorage.cpp:592
bool IsValidPos(uint16 pos, bool explicit_pos)
Definition: Player.h:1263

References _player, Player::CanStoreItem(), Player::CanUnequipItem(), EQUIP_ERR_ITEM_DOESNT_GO_TO_SLOT, EQUIP_ERR_NONE, EQUIP_ERR_OK, Player::GetItemByPos(), Item::GetPos(), Player::IsBagPos(), Player::IsEquipmentPos(), Player::IsValidPos(), NULL_SLOT, Player::RemoveItem(), Player::SendEquipError(), Player::StoreItem(), and Player::UpdateTitansGrip().

Referenced by OpcodeTable::Initialize().

◆ HandleAutoStoreBankItemOpcode()

void WorldSession::HandleAutoStoreBankItemOpcode ( WorldPackets::Bank::AutoStoreBankItem packet)
99{
100 LOG_DEBUG("network", "STORAGE: receive bag = {}, slot = {}", packet.Bag, packet.Slot);
101
102 if (!CanUseBank())
103 {
104 LOG_DEBUG("network", "WORLD: HandleAutoStoreBankItemOpcode - Unit ({}) not found or you can't interact with him.", m_currentBankerGUID.ToString());
105 return;
106 }
107
108 Item* item = _player->GetItemByPos(packet.Bag, packet.Slot);
109 if (!item)
110 return;
111
112 if (_player->IsBankPos(packet.Bag, packet.Slot)) // moving from bank to inventory
113 {
114 ItemPosCountVec dest;
115 InventoryResult msg = _player->CanStoreItem(NULL_BAG, NULL_SLOT, dest, item, false);
116 if (msg != EQUIP_ERR_OK)
117 {
118 _player->SendEquipError(msg, item, nullptr);
119 return;
120 }
121
122 _player->RemoveItem(packet.Bag, packet.Slot, true);
123 if (Item const* storedItem = _player->StoreItem(dest, item, true))
124 _player->ItemAddedQuestCheck(storedItem->GetEntry(), storedItem->GetCount());
125 }
126 else // moving from inventory to bank
127 {
128 ItemPosCountVec dest;
129 InventoryResult msg = _player->CanBankItem(NULL_BAG, NULL_SLOT, dest, item, false);
130 if (msg != EQUIP_ERR_OK)
131 {
132 _player->SendEquipError(msg, item, nullptr);
133 return;
134 }
135
136 _player->RemoveItem(packet.Bag, packet.Slot, true);
138 _player->BankItem(dest, item, true);
140 }
141}
void ItemAddedQuestCheck(uint32 entry, uint32 count)
Definition: PlayerQuest.cpp:1829
uint8 Bag
Definition: BankPackets.h:46
uint8 Slot
Definition: BankPackets.h:47

References _player, WorldPackets::Bank::AutoStoreBankItem::Bag, Player::BankItem(), Player::CanBankItem(), Player::CanStoreItem(), CanUseBank(), EQUIP_ERR_OK, Item::GetCount(), Object::GetEntry(), Player::GetItemByPos(), Player::IsBankPos(), Player::ItemAddedQuestCheck(), Player::ItemRemovedQuestCheck(), LOG_DEBUG, m_currentBankerGUID, NULL_BAG, NULL_SLOT, Player::RemoveItem(), Player::SendEquipError(), WorldPackets::Bank::AutoStoreBankItem::Slot, Player::StoreItem(), ObjectGuid::ToString(), and Player::UpdateTitansGrip().

Referenced by OpcodeTable::Initialize().

◆ HandleAutostoreLootItemOpcode()

void WorldSession::HandleAutostoreLootItemOpcode ( WorldPacket recvPacket)
34{
35 LOG_DEBUG("network", "WORLD: CMSG_AUTOSTORE_LOOT_ITEM");
36 Player* player = GetPlayer();
37 ObjectGuid lguid = player->GetLootGUID();
38 Loot* loot = nullptr;
39 uint8 lootSlot = 0;
40
41 recvData >> lootSlot;
42
43 if (lguid.IsGameObject())
44 {
45 GameObject* go = player->GetMap()->GetGameObject(lguid);
46 // xinef: cheating protection
47 //if (player->GetGroup() && player->GetGroup()->GetLootMethod() == MASTER_LOOT && player->GetGUID() != player->GetGroup()->GetMasterLooterGuid())
48 // go = nullptr;
49
50 // not check distance for GO in case owned GO (fishing bobber case, for example) or Fishing hole GO
51 if (!go || ((go->GetOwnerGUID() != _player->GetGUID() && go->GetGoType() != GAMEOBJECT_TYPE_FISHINGHOLE) && !go->IsWithinDistInMap(_player)))
52 {
53 player->SendLootRelease(lguid);
54 return;
55 }
56
57 loot = &go->loot;
58 }
59 else if (lguid.IsItem())
60 {
61 Item* pItem = player->GetItemByGuid(lguid);
62
63 if (!pItem)
64 {
65 player->SendLootRelease(lguid);
66 return;
67 }
68
69 loot = &pItem->loot;
70 }
71 else if (lguid.IsCorpse())
72 {
73 Corpse* bones = ObjectAccessor::GetCorpse(*player, lguid);
74 if (!bones)
75 {
76 player->SendLootRelease(lguid);
77 return;
78 }
79
80 loot = &bones->loot;
81 }
82 else
83 {
84 Creature* creature = GetPlayer()->GetMap()->GetCreature(lguid);
85
86 bool lootAllowed = creature && creature->IsAlive() == (player->IsClass(CLASS_ROGUE, CLASS_CONTEXT_ABILITY) && creature->loot.loot_type == LOOT_PICKPOCKETING);
87 if (!lootAllowed || !creature->IsWithinDistInMap(_player, INTERACTION_DISTANCE))
88 {
89 player->SendLootError(lguid, lootAllowed ? LOOT_ERROR_TOO_FAR : LOOT_ERROR_DIDNT_KILL);
90 return;
91 }
92
93 loot = &creature->loot;
94 }
95
96 sScriptMgr->OnAfterCreatureLoot(player);
97
99 LootItem* lootItem = player->StoreLootItem(lootSlot, loot, msg);
100 if (msg != EQUIP_ERR_OK && lguid.IsItem() && loot->loot_type != LOOT_CORPSE)
101 {
102 lootItem->is_looted = true;
103 loot->NotifyItemRemoved(lootItem->itemIndex);
104 loot->unlootedCount--;
105
106 player->SendItemRetrievalMail(lootItem->itemid, lootItem->count);
107 }
108
109 // If player is removing the last LootItem, delete the empty container.
110 if (loot->isLooted() && lguid.IsItem())
111 DoLootRelease(lguid);
112}
@ LOOT_ERROR_TOO_FAR
Definition: LootMgr.h:98
@ LOOT_ERROR_DIDNT_KILL
Definition: LootMgr.h:97
@ LOOT_CORPSE
Definition: LootMgr.h:81
void SendItemRetrievalMail(uint32 itemEntry, uint32 count)
Definition: PlayerMisc.cpp:439
ObjectGuid GetLootGUID() const
Definition: Player.h:1975
void SendLootError(ObjectGuid guid, LootError error)
Definition: Player.cpp:8164
LootItem * StoreLootItem(uint8 lootSlot, Loot *loot, InventoryResult &msg)
Definition: Player.cpp:13518
Definition: LootMgr.h:155
uint32 itemid
Definition: LootMgr.h:156
uint32 itemIndex
Definition: LootMgr.h:157
uint8 count
Definition: LootMgr.h:163
bool is_looted
Definition: LootMgr.h:164
uint8 unlootedCount
Definition: LootMgr.h:323
void NotifyItemRemoved(uint8 lootIndex)
Definition: LootMgr.cpp:766
void DoLootRelease(ObjectGuid lguid)
Definition: LootHandler.cpp:270

References _player, CLASS_CONTEXT_ABILITY, CLASS_ROGUE, LootItem::count, DoLootRelease(), EQUIP_ERR_OK, GAMEOBJECT_TYPE_FISHINGHOLE, ObjectAccessor::GetCorpse(), Map::GetCreature(), Map::GetGameObject(), GameObject::GetGoType(), Object::GetGUID(), Player::GetItemByGuid(), Player::GetLootGUID(), WorldObject::GetMap(), GameObject::GetOwnerGUID(), GetPlayer(), INTERACTION_DISTANCE, LootItem::is_looted, Unit::IsAlive(), Player::IsClass(), ObjectGuid::IsCorpse(), ObjectGuid::IsGameObject(), ObjectGuid::IsItem(), Loot::isLooted(), GameObject::IsWithinDistInMap(), WorldObject::IsWithinDistInMap(), LootItem::itemid, LootItem::itemIndex, LOG_DEBUG, Corpse::loot, Creature::loot, GameObject::loot, Item::loot, LOOT_CORPSE, LOOT_ERROR_DIDNT_KILL, LOOT_ERROR_TOO_FAR, LOOT_PICKPOCKETING, Loot::loot_type, Loot::NotifyItemRemoved(), Player::SendItemRetrievalMail(), Player::SendLootError(), Player::SendLootRelease(), sScriptMgr, Player::StoreLootItem(), and Loot::unlootedCount.

Referenced by OpcodeTable::Initialize().

◆ HandleBankerActivateOpcode()

void WorldSession::HandleBankerActivateOpcode ( WorldPacket recvData)
45{
46 ObjectGuid guid;
47
48 recvData >> guid;
49
51 if (!unit)
52 {
53 LOG_DEBUG("network", "WORLD: HandleBankerActivateOpcode - Unit ({}) not found or you can not interact with him.", guid.ToString());
54 return;
55 }
56
57 // remove fake death
58 if (GetPlayer()->HasUnitState(UNIT_STATE_DIED))
60
61 SendShowBank(guid);
62}
void SendShowBank(ObjectGuid guid)
Definition: BankHandler.cpp:188

References Player::GetNPCIfCanInteractWith(), GetPlayer(), LOG_DEBUG, Unit::RemoveAurasByType(), SendShowBank(), SPELL_AURA_FEIGN_DEATH, ObjectGuid::ToString(), UNIT_NPC_FLAG_BANKER, and UNIT_STATE_DIED.

Referenced by OpcodeTable::Initialize().

◆ HandleBattlefieldLeaveOpcode()

void WorldSession::HandleBattlefieldLeaveOpcode ( WorldPacket recvData)
590{
591 LOG_DEBUG("network", "WORLD: Recvd CMSG_LEAVE_BATTLEFIELD Message");
592
593 recvData.read_skip<uint8>(); // unk1
594 recvData.read_skip<uint8>(); // unk2
595 recvData.read_skip<uint32>(); // BattlegroundTypeId
596 recvData.read_skip<uint16>(); // unk3
597
598 // not allow leave battleground in combat
599 if (_player->IsInCombat())
601 if (bg->GetStatus() != STATUS_WAIT_LEAVE)
602 return;
603
605}
@ STATUS_WAIT_LEAVE
Definition: Battleground.h:203
void LeaveBattleground(Battleground *bg=nullptr)
Definition: Player.cpp:11318
bool IsInCombat() const
Definition: Unit.h:820

References _player, Player::GetBattleground(), Unit::IsInCombat(), Player::LeaveBattleground(), LOG_DEBUG, ByteBuffer::read_skip(), and STATUS_WAIT_LEAVE.

Referenced by OpcodeTable::Initialize().

◆ HandleBattlefieldListOpcode()

void WorldSession::HandleBattlefieldListOpcode ( WorldPacket recvData)
367{
368 LOG_DEBUG("network", "WORLD: Recvd CMSG_BATTLEFIELD_LIST Message");
369
370 uint32 bgTypeId;
371 recvData >> bgTypeId; // id from DBC
372
373 uint8 fromWhere;
374 recvData >> fromWhere; // 0 - battlemaster (lua: ShowBattlefieldList), 1 - UI (lua: RequestBattlegroundInstanceInfo)
375
376 uint8 canGainXP;
377 recvData >> canGainXP; // players with locked xp have their own bg queue on retail
378
379 BattlemasterListEntry const* bl = sBattlemasterListStore.LookupEntry(bgTypeId);
380 if (!bl)
381 {
382 LOG_DEBUG("bg.battleground", "BattlegroundHandler: invalid bgtype ({}) with player (Name: {}, {}) received.", bgTypeId, _player->GetName(), _player->GetGUID().ToString());
383 return;
384 }
385
386 WorldPacket data;
387 sBattlegroundMgr->BuildBattlegroundListPacket(&data, ObjectGuid::Empty, _player, BattlegroundTypeId(bgTypeId), fromWhere);
388 SendPacket(&data);
389}
DBCStorage< BattlemasterListEntry > sBattlemasterListStore(BattlemasterListEntryfmt)
BattlegroundTypeId
Definition: SharedDefines.h:3479
Definition: DBCStructure.h:603

References _player, ObjectGuid::Empty, Object::GetGUID(), WorldObject::GetName(), LOG_DEBUG, sBattlegroundMgr, sBattlemasterListStore, SendPacket(), and ObjectGuid::ToString().

Referenced by OpcodeTable::Initialize().

◆ HandleBattleFieldPortOpcode()

void WorldSession::HandleBattleFieldPortOpcode ( WorldPacket recvData)
392{
393 uint8 arenaType; // arenatype if arena
394 uint8 unk2; // unk, can be 0x0 (may be if was invited?) and 0x1
395 uint32 bgTypeId_; // type id from dbc
396 uint16 unk; // 0x1F90 constant?
397 uint8 action; // enter battle 0x1, leave queue 0x0
398
399 recvData >> arenaType >> unk2 >> bgTypeId_ >> unk >> action;
400
401 // bgTypeId not valid
402 if (!sBattlemasterListStore.LookupEntry(bgTypeId_))
403 {
404 LOG_DEBUG("bg.battleground", "CMSG_BATTLEFIELD_PORT {} ArenaType: {}, Unk: {}, BgType: {}, Action: {}. Invalid BgType!", GetPlayerInfo(), arenaType, unk2, bgTypeId_, action);
405 return;
406 }
407
408 // player not in any queue, so can't really answer
410 {
411 LOG_DEBUG("bg.battleground", "CMSG_BATTLEFIELD_PORT {} ArenaType: {}, Unk: {}, BgType: {}, Action: {}. Player not in queue!", GetPlayerInfo(), arenaType, unk2, bgTypeId_, action);
412 return;
413 }
414
416 {
418 return;
419 }
420
421 // get BattlegroundQueue for received
422 BattlegroundTypeId bgTypeId = BattlegroundTypeId(bgTypeId_);
423 BattlegroundQueueTypeId bgQueueTypeId = BattlegroundMgr::BGQueueTypeId(bgTypeId, arenaType);
424 BattlegroundQueue& bgQueue = sBattlegroundMgr->GetBattlegroundQueue(bgQueueTypeId);
425
426 if (!sScriptMgr->CanBattleFieldPort(_player, arenaType, bgTypeId, action))
427 return;
428
429 // get group info from queue
430 GroupQueueInfo ginfo;
431 if (!bgQueue.GetPlayerGroupInfoData(_player->GetGUID(), &ginfo))
432 {
433 LOG_DEBUG("bg.battleground", "CMSG_BATTLEFIELD_PORT {} ArenaType: {}, Unk: {}, BgType: {}, Action: {}. Player not in queue (No player Group Info)!",
434 GetPlayerInfo(), arenaType, unk2, bgTypeId_, action);
435 return;
436 }
437
438 // to accept, player must be invited to particular battleground id
439 if (!ginfo.IsInvitedToBGInstanceGUID && action == 1)
440 {
441 LOG_DEBUG("bg.battleground", "CMSG_BATTLEFIELD_PORT {} ArenaType: {}, Unk: {}, BgType: {}, Action: {}. Player is not invited to any bg!",
442 GetPlayerInfo(), arenaType, unk2, bgTypeId_, action);
443 return;
444 }
445
446 Battleground* bg = sBattlegroundMgr->GetBattleground(ginfo.IsInvitedToBGInstanceGUID, bgTypeId);
447 if (!bg)
448 {
449 if (action)
450 {
451 LOG_DEBUG("bg.battleground", "CMSG_BATTLEFIELD_PORT {} ArenaType: {}, Unk: {}, BgType: {}, Action: {}. Cant find BG with id {}!",
452 GetPlayerInfo(), arenaType, unk2, bgTypeId_, action, ginfo.IsInvitedToBGInstanceGUID);
453 return;
454 }
455
456 bg = sBattlegroundMgr->GetBattlegroundTemplate(bgTypeId);
457 if (!bg)
458 {
459 LOG_ERROR("network", "BattlegroundHandler: bg_template not found for type id {}.", bgTypeId);
460 return;
461 }
462 }
463
464 LOG_DEBUG("bg.battleground", "CMSG_BATTLEFIELD_PORT {} ArenaType: {}, Unk: {}, BgType: {}, Action: {}.",
465 GetPlayerInfo(), arenaType, unk2, bgTypeId_, action);
466
467 // expected bracket entry
469 if (!bracketEntry)
470 return;
471
472 // safety checks
473 if (action == 1 && ginfo.ArenaType == 0)
474 {
475 // can't join with deserter, check it here right before joining to be sure
477 {
478 WorldPacket data;
479 sBattlegroundMgr->BuildGroupJoinedBattlegroundPacket(&data, ERR_GROUP_JOIN_BATTLEGROUND_DESERTERS);
480 SendPacket(&data);
481 action = 0;
482 LOG_DEBUG("bg.battleground", "Player {} {} has a deserter debuff, do not port him to battleground!", _player->GetName(), _player->GetGUID().ToString());
483 }
484
485 if (_player->GetLevel() > bg->GetMaxLevel())
486 {
487 LOG_ERROR("network", "Player {} {} has level ({}) higher than maxlevel ({}) of battleground ({})! Do not port him to battleground!",
489 action = 0;
490 }
491 }
492
493 // get player queue slot index for this bg (can be in up to 2 queues at the same time)
494 uint32 queueSlot = _player->GetBattlegroundQueueIndex(bgQueueTypeId);
495 WorldPacket data;
496
497 if (action) // accept
498 {
499 // check Freeze debuff
500 if (_player->HasAura(9454))
501 return;
502
503 if (!_player->IsInvitedForBattlegroundQueueType(bgQueueTypeId))
504 return; // cheating?
505
506 // set entry point if not in battleground
507 if (!_player->InBattleground())
509
510 // resurrect the player
511 if (!_player->IsAlive())
512 {
515 }
516
517 TeamId teamId = ginfo.teamId;
518
519 // send status packet
520 sBattlegroundMgr->BuildBattlegroundStatusPacket(&data, bg, queueSlot, STATUS_IN_PROGRESS, 0, bg->GetStartTime(), bg->GetArenaType(), teamId);
521 SendPacket(&data);
522
523 // remove battleground queue status from BGmgr
524 bgQueue.RemovePlayer(_player->GetGUID(), false);
525
526 // this is still needed here if battleground "jumping" shouldn't add deserter debuff
527 // also this is required to prevent stuck at old battleground after SetBattlegroundId set to new
528 if (Battleground* currentBg = _player->GetBattleground())
529 currentBg->RemovePlayerAtLeave(_player);
530
531 for (uint8 i = 0; i < PLAYER_MAX_BATTLEGROUND_QUEUES; ++i)
532 {
533 auto playerBgQueueTypeId = _player->GetBattlegroundQueueTypeId(i);
534 if (playerBgQueueTypeId != BATTLEGROUND_QUEUE_NONE && playerBgQueueTypeId != bgQueueTypeId)
535 {
536 _player->RemoveBattlegroundQueueId(playerBgQueueTypeId);
537 sBattlegroundMgr->GetBattlegroundQueue(playerBgQueueTypeId).RemovePlayer(_player->GetGUID(), true);
538 }
539 }
540
541 // Remove from LFG queues
542 sLFGMgr->LeaveAllLfgQueues(_player->GetGUID(), false);
543
544 _player->SetBattlegroundId(bg->GetInstanceID(), bg->GetBgTypeID(), queueSlot, true, bgTypeId == BATTLEGROUND_RB, teamId);
545 sBattlegroundMgr->SendToBattleground(_player, ginfo.IsInvitedToBGInstanceGUID, bgTypeId);
546
547 LOG_DEBUG("bg.battleground", "Battleground: player {} {} joined battle for bg {}, bgtype {}, queue type {}.", _player->GetName(), _player->GetGUID().ToString(), bg->GetInstanceID(), bg->GetBgTypeID(), bgQueueTypeId);
548 }
549 else // leave queue
550 {
551 for (auto const& playerGuid : ginfo.Players)
552 {
553 auto player = ObjectAccessor::FindConnectedPlayer(playerGuid);
554 if (!player)
555 continue;
556
557 bgQueue.RemovePlayer(playerGuid, true);
558 player->RemoveBattlegroundQueueId(bgQueueTypeId);
559
560 sBattlegroundMgr->BuildBattlegroundStatusPacket(&data, bg, queueSlot, STATUS_NONE, 0, 0, 0, TEAM_NEUTRAL);
561 player->SendDirectMessage(&data);
562
563 LOG_DEBUG("bg.battleground", "Battleground: player {} {} left queue for bgtype {}, queue type {}.", player->GetName(), playerGuid.ToString(), bg->GetBgTypeID(), bgQueueTypeId);
564 }
565
566 // player left queue, we should update it - do not update Arena Queue
567 if (!ginfo.ArenaType)
568 sBattlegroundMgr->ScheduleQueueUpdate(ginfo.ArenaMatchmakerRating, ginfo.ArenaType, bgQueueTypeId, bgTypeId, bracketEntry->GetBracketId());
569
570 // track if player refuses to join the BG after being invited
571 if (bg->isBattleground() && (bg->GetStatus() == STATUS_IN_PROGRESS || bg->GetStatus() == STATUS_WAIT_JOIN))
572 {
574 {
576 stmt->SetData(0, _player->GetGUID().GetCounter());
578 CharacterDatabase.Execute(stmt);
579 }
580
581 sScriptMgr->OnBattlegroundDesertion(_player, BG_DESERTION_TYPE_LEAVE_QUEUE);
582 }
583
584 if (bg->isArena() && (bg->GetStatus() == STATUS_IN_PROGRESS || bg->GetStatus() == STATUS_WAIT_JOIN))
585 sScriptMgr->OnBattlegroundDesertion(_player, ARENA_DESERTION_TYPE_LEAVE_QUEUE);
586 }
587}
@ ARENA_DESERTION_TYPE_LEAVE_QUEUE
Definition: Battleground.h:57
@ BG_DESERTION_TYPE_LEAVE_QUEUE
Definition: Battleground.h:53
@ STATUS_NONE
Definition: Battleground.h:199
@ STATUS_WAIT_JOIN
Definition: Battleground.h:201
#define sLFGMgr
Definition: LFGMgr.h:641
PvPDifficultyEntry const * GetBattlegroundBracketByLevel(uint32 mapid, uint32 level)
Definition: DBCStores.cpp:793
@ CONFIG_BATTLEGROUND_TRACK_DESERTERS
Definition: IWorld.h:116
@ LANG_YOU_IN_COMBAT
Definition: Language.h:55
@ CHAR_INS_DESERTER_TRACK
Definition: CharacterDatabase.h:499
@ ERR_GROUP_JOIN_BATTLEGROUND_DESERTERS
Definition: SharedDefines.h:3639
@ BATTLEGROUND_RB
Definition: SharedDefines.h:3493
@ BATTLEGROUND_QUEUE_NONE
Definition: SharedDefines.h:3620
@ TEAM_NEUTRAL
Definition: SharedDefines.h:762
#define PLAYER_MAX_BATTLEGROUND_QUEUES
Definition: SharedDefines.h:176
uint32 GetMapId() const
Definition: Battleground.h:445
uint8 GetArenaType() const
Definition: Battleground.h:357
uint32 GetInstanceID() const
Definition: Battleground.h:331
bool isArena() const
Definition: Battleground.h:413
uint32 GetStartTime() const
Definition: Battleground.h:334
bool isBattleground() const
Definition: Battleground.h:414
BattlegroundStatus GetStatus() const
Definition: Battleground.h:332
uint32 GetMaxLevel() const
Definition: Battleground.h:339
BattlegroundTypeId GetBgTypeID(bool GetRandom=false) const
Definition: Battleground.h:329
TeamId teamId
Definition: BattlegroundQueue.h:33
uint8 ArenaType
Definition: BattlegroundQueue.h:37
GuidSet Players
Definition: BattlegroundQueue.h:32
uint32 ArenaMatchmakerRating
Definition: BattlegroundQueue.h:43
void RemovePlayer(ObjectGuid guid, bool decreaseInvitedCount)
Definition: BattlegroundQueue.cpp:261
bool IsInvitedForBattlegroundQueueType(BattlegroundQueueTypeId bgQueueTypeId) const
Definition: Player.cpp:12229
void SetEntryPoint()
Definition: Player.cpp:11281
bool InBattleground() const
Definition: Player.h:2234
bool InBattlegroundQueue(bool ignoreArena=false) const
Definition: Player.cpp:12204
void SetBattlegroundId(uint32 id, BattlegroundTypeId bgTypeId, uint32 queueSlot, bool invited, bool isRandom, TeamId teamId)
Definition: Player.cpp:12305
void RemoveBattlegroundQueueId(BattlegroundQueueTypeId val)
Definition: Player.cpp:12267
bool CanJoinToBattleground() const
Definition: Player.cpp:11358
uint32 GetBattlegroundQueueIndex(BattlegroundQueueTypeId bgQueueTypeId) const
Definition: Player.cpp:12220
BattlegroundQueueTypeId GetBattlegroundQueueTypeId(uint32 index) const
Definition: Player.cpp:12215
bool HasAura(uint32 spellId, ObjectGuid casterGUID=ObjectGuid::Empty, ObjectGuid itemCasterGUID=ObjectGuid::Empty, uint8 reqEffMask=0) const
Definition: Unit.cpp:5676
ObjectGuid GetCharmGUID() const
Definition: Unit.h:1230
Definition: DBCStructure.h:1430
BattlegroundBracketId GetBracketId() const
Definition: DBCStructure.h:1440

References _player, ARENA_DESERTION_TYPE_LEAVE_QUEUE, GroupQueueInfo::ArenaMatchmakerRating, GroupQueueInfo::ArenaType, BATTLEGROUND_QUEUE_NONE, BATTLEGROUND_RB, BG_DESERTION_TYPE_LEAVE_QUEUE, BattlegroundMgr::BGQueueTypeId(), Player::CanJoinToBattleground(), CHAR_INS_DESERTER_TRACK, CharacterDatabase, CONFIG_BATTLEGROUND_TRACK_DESERTERS, ERR_GROUP_JOIN_BATTLEGROUND_DESERTERS, ObjectAccessor::FindConnectedPlayer(), Battleground::GetArenaType(), Player::GetBattleground(), GetBattlegroundBracketByLevel(), Player::GetBattlegroundQueueIndex(), Player::GetBattlegroundQueueTypeId(), Battleground::GetBgTypeID(), PvPDifficultyEntry::GetBracketId(), Unit::GetCharmGUID(), ObjectGuid::GetCounter(), Object::GetGUID(), Battleground::GetInstanceID(), Unit::GetLevel(), Battleground::GetMapId(), Battleground::GetMaxLevel(), WorldObject::GetName(), BattlegroundQueue::GetPlayerGroupInfoData(), GetPlayerInfo(), Player::GetSession(), Battleground::GetStartTime(), Battleground::GetStatus(), Unit::HasAura(), Player::InBattleground(), Player::InBattlegroundQueue(), Unit::IsAlive(), Battleground::isArena(), Battleground::isBattleground(), Unit::IsInCombat(), Player::IsInvitedForBattlegroundQueueType(), GroupQueueInfo::IsInvitedToBGInstanceGUID, LANG_YOU_IN_COMBAT, LOG_DEBUG, LOG_ERROR, PLAYER_MAX_BATTLEGROUND_QUEUES, GroupQueueInfo::Players, Player::RemoveBattlegroundQueueId(), BattlegroundQueue::RemovePlayer(), Player::ResurrectPlayer(), sBattlegroundMgr, sBattlemasterListStore, ChatHandler::SendNotification(), SendPacket(), Player::SetBattlegroundId(), PreparedStatementBase::SetData(), Player::SetEntryPoint(), sLFGMgr, Player::SpawnCorpseBones(), sScriptMgr, STATUS_IN_PROGRESS, STATUS_NONE, STATUS_WAIT_JOIN, sWorld, TEAM_NEUTRAL, GroupQueueInfo::teamId, and ObjectGuid::ToString().

Referenced by OpcodeTable::Initialize().

◆ HandleBattlefieldStatusOpcode()

void WorldSession::HandleBattlefieldStatusOpcode ( WorldPacket recvData)
608{
609 // requested at login and on map change
610 // send status for current queues and current bg
611
612 WorldPacket data;
613
614 // for current bg send STATUS_IN_PROGRESS
616 if (bg->GetPlayers().count(_player->GetGUID()))
617 {
618 sBattlegroundMgr->BuildBattlegroundStatusPacket(&data, bg, _player->GetCurrentBattlegroundQueueSlot(), STATUS_IN_PROGRESS, bg->GetEndTime(), bg->GetStartTime(), bg->GetArenaType(), _player->GetBgTeamId());
619 SendPacket(&data);
620 }
621
622 // for queued bgs send STATUS_WAIT_JOIN or STATUS_WAIT_QUEUE
623 for (uint8 i = 0; i < PLAYER_MAX_BATTLEGROUND_QUEUES; ++i)
624 {
625 // check if in queue
627 if (!bgQueueTypeId)
628 continue;
629
630 // get group info from queue
631 BattlegroundQueue& bgQueue = sBattlegroundMgr->GetBattlegroundQueue(bgQueueTypeId);
632 GroupQueueInfo ginfo;
633 if (!bgQueue.GetPlayerGroupInfoData(_player->GetGUID(), &ginfo))
634 continue;
635
636 BattlegroundTypeId bgTypeId = BattlegroundMgr::BGTemplateId(bgQueueTypeId);
637
638 // if invited - send STATUS_WAIT_JOIN
640 {
641 Battleground* bg = sBattlegroundMgr->GetBattleground(ginfo.IsInvitedToBGInstanceGUID, bgTypeId);
642 if (!bg)
643 continue;
644
645 uint32 remainingTime = (GameTime::GetGameTimeMS().count() < ginfo.RemoveInviteTime ? getMSTimeDiff(GameTime::GetGameTimeMS().count(), ginfo.RemoveInviteTime) : 1);
646 sBattlegroundMgr->BuildBattlegroundStatusPacket(&data, bg, i, STATUS_WAIT_JOIN, remainingTime, 0, ginfo.ArenaType, TEAM_NEUTRAL, bg->isRated(), ginfo.BgTypeId);
647 SendPacket(&data);
648 }
649 // if not invited - send STATUS_WAIT_QUEUE
650 else
651 {
652 Battleground* bgt = sBattlegroundMgr->GetBattlegroundTemplate(bgTypeId);
653 if (!bgt)
654 continue;
655
656 // expected bracket entry
658 if (!bracketEntry)
659 continue;
660
661 uint32 avgWaitTime = bgQueue.GetAverageQueueWaitTime(&ginfo);
662 sBattlegroundMgr->BuildBattlegroundStatusPacket(&data, bgt, i, STATUS_WAIT_QUEUE, avgWaitTime, getMSTimeDiff(ginfo.JoinTime, GameTime::GetGameTimeMS().count()), ginfo.ArenaType, TEAM_NEUTRAL, ginfo.IsRated);
663 SendPacket(&data);
664 }
665 }
666}
uint32 getMSTimeDiff(uint32 oldMSTime, uint32 newMSTime)
Definition: Timer.h:110
@ STATUS_WAIT_QUEUE
Definition: Battleground.h:200
bool isRated() const
Definition: Battleground.h:415
static BattlegroundTypeId BGTemplateId(BattlegroundQueueTypeId bgQueueTypeId)
Definition: BattlegroundMgr.cpp:696
uint32 JoinTime
Definition: BattlegroundQueue.h:39
BattlegroundTypeId BgTypeId
Definition: BattlegroundQueue.h:35
uint32 RemoveInviteTime
Definition: BattlegroundQueue.h:40
bool IsRated
Definition: BattlegroundQueue.h:36
uint32 GetAverageQueueWaitTime(GroupQueueInfo *ginfo) const
Definition: BattlegroundQueue.cpp:235
uint32 GetCurrentBattlegroundQueueSlot() const
Definition: Player.h:2238
TeamId GetBgTeamId() const
Definition: Player.h:2260

References _player, GroupQueueInfo::ArenaType, BattlegroundMgr::BGTemplateId(), GroupQueueInfo::BgTypeId, BattlegroundQueue::GetAverageQueueWaitTime(), Player::GetBattleground(), GetBattlegroundBracketByLevel(), Player::GetBattlegroundQueueTypeId(), Player::GetBgTeamId(), Player::GetCurrentBattlegroundQueueSlot(), GameTime::GetGameTimeMS(), Object::GetGUID(), Unit::GetLevel(), Battleground::GetMapId(), getMSTimeDiff(), BattlegroundQueue::GetPlayerGroupInfoData(), GroupQueueInfo::IsInvitedToBGInstanceGUID, Battleground::isRated(), GroupQueueInfo::IsRated, GroupQueueInfo::JoinTime, PLAYER_MAX_BATTLEGROUND_QUEUES, GroupQueueInfo::RemoveInviteTime, sBattlegroundMgr, SendPacket(), STATUS_IN_PROGRESS, STATUS_WAIT_JOIN, STATUS_WAIT_QUEUE, and TEAM_NEUTRAL.

Referenced by OpcodeTable::Initialize().

◆ HandleBattlegroundPlayerPositionsOpcode()

void WorldSession::HandleBattlegroundPlayerPositionsOpcode ( WorldPacket recvData)
297{
298 LOG_DEBUG("network", "WORLD: Recvd MSG_BATTLEGROUND_PLAYER_POSITIONS Message");
299
301 if (!bg) // can't be received if player not in battleground
302 return;
303
304 uint32 flagCarrierCount = 0;
305 Player* allianceFlagCarrier = nullptr;
306 Player* hordeFlagCarrier = nullptr;
307
309 {
310 allianceFlagCarrier = ObjectAccessor::FindPlayer(guid);
311 if (allianceFlagCarrier)
312 ++flagCarrierCount;
313 }
314
316 {
317 hordeFlagCarrier = ObjectAccessor::FindPlayer(guid);
318 if (hordeFlagCarrier)
319 ++flagCarrierCount;
320 }
321
322 WorldPacket data(MSG_BATTLEGROUND_PLAYER_POSITIONS, 4 + 4 + 16 * flagCarrierCount);
323 // Used to send several player positions (found used in AV)
324 data << 0; // CGBattlefieldInfo__m_numPlayerPositions
325 /*
326 for (CGBattlefieldInfo__m_numPlayerPositions)
327 data << guid << posx << posy;
328 */
329 data << flagCarrierCount;
330 if (allianceFlagCarrier)
331 {
332 data << allianceFlagCarrier->GetGUID();
333 data << float(allianceFlagCarrier->GetPositionX());
334 data << float(allianceFlagCarrier->GetPositionY());
335 }
336
337 if (hordeFlagCarrier)
338 {
339 data << hordeFlagCarrier->GetGUID();
340 data << float(hordeFlagCarrier->GetPositionX());
341 data << float(hordeFlagCarrier->GetPositionY());
342 }
343
344 SendPacket(&data);
345}
@ TEAM_HORDE
Definition: SharedDefines.h:761
@ MSG_BATTLEGROUND_PLAYER_POSITIONS
Definition: Opcodes.h:775
Player * FindPlayer(ObjectGuid const guid)
Definition: ObjectAccessor.cpp:245
virtual ObjectGuid GetFlagPickerGUID(TeamId=TEAM_NEUTRAL) const
Definition: Battleground.h:575

References _player, ObjectAccessor::FindPlayer(), Player::GetBattleground(), Battleground::GetFlagPickerGUID(), Object::GetGUID(), Position::GetPositionX(), Position::GetPositionY(), LOG_DEBUG, MSG_BATTLEGROUND_PLAYER_POSITIONS, SendPacket(), TEAM_ALLIANCE, and TEAM_HORDE.

Referenced by OpcodeTable::Initialize().

◆ HandleBattlemasterHelloOpcode()

void WorldSession::HandleBattlemasterHelloOpcode ( WorldPacket recvData)
36{
37 ObjectGuid guid;
38 recvData >> guid;
39 LOG_DEBUG("network", "WORLD: Recvd CMSG_BATTLEMASTER_HELLO Message from ({})", guid.ToString());
40
41 Creature* unit = GetPlayer()->GetMap()->GetCreature(guid);
42 if (!unit)
43 return;
44
45 if (!unit->IsBattleMaster()) // it's not battlemaster
46 return;
47
48 // Stop the npc if moving
50 unit->PauseMovement(pause);
51 unit->SetHomePosition(unit->GetPosition());
52
53 BattlegroundTypeId bgTypeId = sBattlegroundMgr->GetBattleMasterBG(unit->GetEntry());
54
55 if (!_player->GetBGAccessByLevel(bgTypeId))
56 {
57 // temp, must be gossip message...
59 return;
60 }
61
62 SendBattleGroundList(guid, bgTypeId);
63}
@ LANG_YOUR_BG_LEVEL_REQ_ERROR
Definition: Language.h:686
void SetHomePosition(float x, float y, float z, float o)
Definition: Creature.h:339
CreatureMovementData const & GetMovementTemplate() const
Definition: Creature.cpp:2979
uint32 GetInteractionPauseTimer() const
Definition: CreatureData.h:161
void GetPosition(float &x, float &y) const
Definition: Position.h:122
bool GetBGAccessByLevel(BattlegroundTypeId bgTypeId) const
Definition: Player.cpp:12317
bool IsBattleMaster() const
Definition: Unit.h:722
virtual void PauseMovement(uint32 timer=0, uint8 slot=0)
Disable the unit movement by clearing UNIT_STATE_MOVING and stopping the spline.
Definition: Unit.cpp:16634
void SendBattleGroundList(ObjectGuid guid, BattlegroundTypeId bgTypeId=BATTLEGROUND_RB)
Definition: BattleGroundHandler.cpp:65

References _player, Player::GetBGAccessByLevel(), Map::GetCreature(), Object::GetEntry(), CreatureMovementData::GetInteractionPauseTimer(), WorldObject::GetMap(), Creature::GetMovementTemplate(), GetPlayer(), Position::GetPosition(), Unit::IsBattleMaster(), LANG_YOUR_BG_LEVEL_REQ_ERROR, LOG_DEBUG, Unit::PauseMovement(), sBattlegroundMgr, SendBattleGroundList(), ChatHandler::SendNotification(), Creature::SetHomePosition(), and ObjectGuid::ToString().

Referenced by OpcodeTable::Initialize().

◆ HandleBattlemasterJoinArena()

void WorldSession::HandleBattlemasterJoinArena ( WorldPacket recvData)
669{
670 LOG_DEBUG("network", "WORLD: CMSG_BATTLEMASTER_JOIN_ARENA");
671
672 ObjectGuid guid; // arena Battlemaster guid
673 uint8 arenaslot; // 2v2, 3v3 or 5v5
674 uint8 asGroup; // asGroup
675 uint8 isRated; // isRated
676
677 recvData >> guid >> arenaslot >> asGroup >> isRated;
678
679 // can't queue for rated without a group
680 if (isRated && !asGroup)
681 return;
682
683 // ignore if we already in BG or BG queue
684 if (_player->InBattleground())
685 return;
686
687 // find creature by guid
688 Creature* unit = GetPlayer()->GetMap()->GetCreature(guid);
689 if (!unit || !unit->IsBattleMaster())
690 return;
691
692 // get arena type
693 uint8 arenatype = 0;
694 uint32 ateamId = 0;
695 uint32 arenaRating = 0;
696 uint32 matchmakerRating = 0;
697 uint32 previousOpponents = 0;
698
699 switch (arenaslot)
700 {
701 case 0:
702 arenatype = ARENA_TYPE_2v2;
703 break;
704 case 1:
705 arenatype = ARENA_TYPE_3v3;
706 break;
707 case 2:
708 arenatype = ARENA_TYPE_5v5;
709 break;
710 default:
711 LOG_ERROR("network", "Unknown arena slot {} at HandleBattlemasterJoinArena()", arenaslot);
712 return;
713 }
714
715 // get template for all arenas
716 Battleground* bgt = sBattlegroundMgr->GetBattlegroundTemplate(BATTLEGROUND_AA);
717 if (!bgt)
718 {
719 LOG_ERROR("network", "Battleground: template bg (all arenas) not found");
720 return;
721 }
722
723 // arenas disabled
725 {
727 return;
728 }
729
730 BattlegroundTypeId bgTypeId = bgt->GetBgTypeID();
731
732 // expected bracket entry
734 if (!bracketEntry)
735 return;
736
737 // must have free queue slot
738 // pussywizard: allow being queued only in one arena queue, and it even cannot be together with bg queues
740 {
741 WorldPacket data;
742 sBattlegroundMgr->BuildGroupJoinedBattlegroundPacket(&data, ERR_BATTLEGROUND_CANNOT_QUEUE_FOR_RATED);
743 SendPacket(&data);
744 return;
745 }
746
747 // queue result (default ok)
749
750 if (!sScriptMgr->CanJoinInArenaQueue(_player, guid, arenaslot, bgTypeId, asGroup, isRated, err) && err <= 0)
751 {
752 WorldPacket data;
753 sBattlegroundMgr->BuildGroupJoinedBattlegroundPacket(&data, err);
754 SendPacket(&data);
755 return;
756 }
757
758 BattlegroundQueueTypeId bgQueueTypeId = BattlegroundMgr::BGQueueTypeId(bgTypeId, arenatype);
759 BattlegroundQueue& bgQueue = sBattlegroundMgr->GetBattlegroundQueue(bgQueueTypeId);
760
761 // check if player can queue:
762 if (!asGroup)
763 {
764 lfg::LfgState lfgState = sLFGMgr->GetState(GetPlayer()->GetGUID());
765 if (GetPlayer()->InBattleground()) // currently in battleground
766 {
768 }
769 else if (lfgState > lfg::LFG_STATE_NONE && (lfgState != lfg::LFG_STATE_QUEUED || !sWorld->getBoolConfig(CONFIG_ALLOW_JOIN_BG_AND_LFG))) // using lfg system
770 {
772 }
773
774 if (err <= 0)
775 {
776 WorldPacket data;
777 sBattlegroundMgr->BuildGroupJoinedBattlegroundPacket(&data, err);
778 SendPacket(&data);
779 return;
780 }
781
782 // check if already in queue
784 //player is already in this queue
785 return;
786
787 // check if has free queue slots
789 return;
790
791 GroupQueueInfo* ginfo = bgQueue.AddGroup(_player, nullptr, bgTypeId, bracketEntry, arenatype, isRated != 0, false, arenaRating, matchmakerRating, ateamId, previousOpponents);
792 uint32 avgWaitTime = bgQueue.GetAverageQueueWaitTime(ginfo);
793 uint32 queueSlot = _player->AddBattlegroundQueueId(bgQueueTypeId);
794
795 WorldPacket data;
796 sBattlegroundMgr->BuildBattlegroundStatusPacket(&data, bgt, queueSlot, STATUS_WAIT_QUEUE, avgWaitTime, 0, arenatype, TEAM_NEUTRAL);
797 SendPacket(&data);
798
799 LOG_DEBUG("bg.battleground", "Battleground: player joined queue for arena, skirmish, bg queue type {} bg type {}: {}, NAME {}", bgQueueTypeId, bgTypeId, _player->GetGUID().ToString(), _player->GetName());
800
801 sScriptMgr->OnPlayerJoinArena(_player);
802 }
803 // check if group can queue:
804 else
805 {
806 Group* grp = _player->GetGroup();
807 // no group or not a leader
808 if (!grp || grp->GetLeaderGUID() != _player->GetGUID())
809 return;
810
811 // additional checks for rated arenas
812 if (isRated)
813 {
814 // pussywizard: for rated matches check if season is in progress!
815 if (!sWorld->getBoolConfig(CONFIG_ARENA_SEASON_IN_PROGRESS))
816 return;
817
818 ateamId = _player->GetArenaTeamId(arenaslot);
819
820 // check team existence
821 ArenaTeam* at = sArenaTeamMgr->GetArenaTeamById(ateamId);
822 if (!at)
823 {
824 SendNotInArenaTeamPacket(arenatype);
825 return;
826 }
827
828 // get team rating for queueing
829 arenaRating = at->GetRating();
830 matchmakerRating = at->GetAverageMMR(grp);
831 if (arenaRating <= 0)
832 arenaRating = 1;
833
834 previousOpponents = at->GetPreviousOpponents();
835 }
836
837 err = grp->CanJoinBattlegroundQueue(bgt, bgQueueTypeId, arenatype, arenatype, (bool)isRated, arenaslot);
838
839 // Check queue group members
840 if (err)
841 {
842 grp->DoForAllMembers([&bgQueue, &err](Player* member)
843 {
844 if (bgQueue.IsPlayerInvitedToRatedArena(member->GetGUID()))
845 {
846 err = ERR_BATTLEGROUND_JOIN_FAILED;
847 }
848 });
849 }
850
851 uint32 avgWaitTime = 0;
852 if (err > 0)
853 {
854 LOG_DEBUG("bg.battleground", "Battleground: arena join as group start");
855
856 if (isRated)
857 {
858 LOG_DEBUG("bg.battleground", "Battleground: arena team id {}, leader {} queued with matchmaker rating {} for type {}", _player->GetArenaTeamId(arenaslot), _player->GetName(), matchmakerRating, arenatype);
859 bgt->SetRated(true);
860 }
861 else
862 {
863 bgt->SetRated(false);
864 }
865
866 GroupQueueInfo* ginfo = bgQueue.AddGroup(_player, grp, bgTypeId, bracketEntry, arenatype, isRated != 0, false, arenaRating, matchmakerRating, ateamId, previousOpponents);
867 avgWaitTime = bgQueue.GetAverageQueueWaitTime(ginfo);
868 }
869
870 WorldPacket data;
871 for (GroupReference* itr = grp->GetFirstMember(); itr != nullptr; itr = itr->next())
872 {
873 Player* member = itr->GetSource();
874 if (!member)
875 continue;
876
877 if (err <= 0)
878 {
879 sBattlegroundMgr->BuildGroupJoinedBattlegroundPacket(&data, err);
880 member->GetSession()->SendPacket(&data);
881 continue;
882 }
883
884 uint32 queueSlot = member->AddBattlegroundQueueId(bgQueueTypeId);
885
886 // send status packet
887 sBattlegroundMgr->BuildBattlegroundStatusPacket(&data, bgt, queueSlot, STATUS_WAIT_QUEUE, avgWaitTime, 0, arenatype, TEAM_NEUTRAL, isRated);
888 member->GetSession()->SendPacket(&data);
889
890 sBattlegroundMgr->BuildGroupJoinedBattlegroundPacket(&data, err);
891 member->GetSession()->SendPacket(&data);
892
893 LOG_DEBUG("bg.battleground", "Battleground: player joined queue for arena as group bg queue type {} bg type {}: {}, NAME {}", bgQueueTypeId, bgTypeId, member->GetGUID().ToString(), member->GetName());
894
895 sScriptMgr->OnPlayerJoinArena(member);
896 }
897 }
898
899 sBattlegroundMgr->ScheduleQueueUpdate(matchmakerRating, arenatype, bgQueueTypeId, bgTypeId, bracketEntry->GetBracketId());
900}
@ DISABLE_TYPE_BATTLEGROUND
Definition: DisableMgr.h:32
@ ARENA_TYPE_5v5
Definition: Battleground.h:219
@ ARENA_TYPE_3v3
Definition: Battleground.h:218
@ ARENA_TYPE_2v2
Definition: Battleground.h:217
@ CONFIG_ARENA_SEASON_IN_PROGRESS
Definition: IWorld.h:119
@ CONFIG_ALLOW_JOIN_BG_AND_LFG
Definition: IWorld.h:172
@ LANG_ARENA_DISABLED
Definition: Language.h:719
GroupJoinBattlegroundResult
Definition: SharedDefines.h:3635
@ ERR_BATTLEGROUND_CANNOT_QUEUE_FOR_RATED
Definition: SharedDefines.h:3642
@ ERR_LFG_CANT_USE_BATTLEGROUND
Definition: SharedDefines.h:3650
@ ERR_BATTLEGROUND_NOT_IN_BATTLEGROUND
Definition: SharedDefines.h:3645
bool IsDisabledFor(DisableType type, uint32 entry, Unit const *unit, uint8 flags)
Definition: DisableMgr.cpp:306
LfgState
Definition: LFG.h:70
@ LFG_STATE_NONE
Definition: LFG.h:71
@ LFG_STATE_QUEUED
Definition: LFG.h:73
uint32 GetPreviousOpponents()
Definition: ArenaTeam.h:212
uint32 GetRating() const
Definition: ArenaTeam.h:158
uint32 GetAverageMMR(Group *group) const
Definition: ArenaTeam.cpp:682
void SetRated(bool state)
Definition: Battleground.h:379
bool IsPlayerInvitedToRatedArena(ObjectGuid pl_guid)
Definition: BattlegroundQueue.cpp:372
GroupQueueInfo * AddGroup(Player *leader, Group *group, BattlegroundTypeId bgTypeId, PvPDifficultyEntry const *bracketEntry, uint8 arenaType, bool isRated, bool isPremade, uint32 arenaRating, uint32 matchmakerRating, uint32 arenaTeamId=0, uint32 opponentsArenaTeamId=0)
Definition: BattlegroundQueue.cpp:134
bool HasFreeBattlegroundQueueId() const
Definition: Player.cpp:12258
uint32 AddBattlegroundQueueId(BattlegroundQueueTypeId val)
Definition: Player.cpp:12243
GroupJoinBattlegroundResult CanJoinBattlegroundQueue(Battleground const *bgTemplate, BattlegroundQueueTypeId bgQueueTypeId, uint32 MinPlayerCount, uint32 MaxPlayerCount, bool isRated, uint32 arenaSlot)
Definition: Group.cpp:1930
GroupReference * GetFirstMember()
Definition: Group.h:243
void DoForAllMembers(std::function< void(Player *)> const &worker)
Definition: Group.cpp:2543
ObjectGuid GetLeaderGUID() const
Definition: Group.cpp:2296
Definition: GroupReference.h:27
GroupReference * next()
Definition: GroupReference.h:36
void SendNotInArenaTeamPacket(uint8 type)
Definition: ArenaTeamHandler.cpp:416

References _player, Player::AddBattlegroundQueueId(), BattlegroundQueue::AddGroup(), ARENA_TYPE_2v2, ARENA_TYPE_3v3, ARENA_TYPE_5v5, BATTLEGROUND_AA, BattlegroundMgr::BGQueueTypeId(), Group::CanJoinBattlegroundQueue(), CONFIG_ALLOW_JOIN_BG_AND_LFG, CONFIG_ARENA_SEASON_IN_PROGRESS, DISABLE_TYPE_BATTLEGROUND, Group::DoForAllMembers(), ERR_BATTLEGROUND_CANNOT_QUEUE_FOR_RATED, ERR_BATTLEGROUND_NOT_IN_BATTLEGROUND, ERR_LFG_CANT_USE_BATTLEGROUND, Player::GetArenaTeamId(), ArenaTeam::GetAverageMMR(), BattlegroundQueue::GetAverageQueueWaitTime(), GetBattlegroundBracketByLevel(), Player::GetBattlegroundQueueIndex(), Battleground::GetBgTypeID(), PvPDifficultyEntry::GetBracketId(), Map::GetCreature(), Group::GetFirstMember(), Player::GetGroup(), Object::GetGUID(), Group::GetLeaderGUID(), Unit::GetLevel(), WorldObject::GetMap(), Battleground::GetMapId(), WorldObject::GetName(), GetPlayer(), ArenaTeam::GetPreviousOpponents(), ArenaTeam::GetRating(), Player::GetSession(), Player::HasFreeBattlegroundQueueId(), Player::InBattleground(), Player::InBattlegroundQueue(), Unit::IsBattleMaster(), DisableMgr::IsDisabledFor(), BattlegroundQueue::IsPlayerInvitedToRatedArena(), LANG_ARENA_DISABLED, lfg::LFG_STATE_NONE, lfg::LFG_STATE_QUEUED, LOG_DEBUG, LOG_ERROR, GroupReference::next(), PLAYER_MAX_BATTLEGROUND_QUEUES, ChatHandler::PSendSysMessage(), sArenaTeamMgr, sBattlegroundMgr, SendNotInArenaTeamPacket(), SendPacket(), Battleground::SetRated(), sLFGMgr, sScriptMgr, STATUS_WAIT_QUEUE, sWorld, TEAM_NEUTRAL, and ObjectGuid::ToString().

Referenced by OpcodeTable::Initialize().

◆ HandleBattlemasterJoinOpcode()

void WorldSession::HandleBattlemasterJoinOpcode ( WorldPacket recvData)
73{
74 ObjectGuid guid;
75 uint32 bgTypeId_;
76 uint32 instanceId;
77 uint8 joinAsGroup;
78 bool isPremade = false;
79
80 recvData >> guid; // battlemaster guid
81 recvData >> bgTypeId_; // battleground type id (DBC id)
82 recvData >> instanceId; // instance id, 0 if First Available selected
83 recvData >> joinAsGroup; // join as group
84
85 // entry not found
86 if (!sBattlemasterListStore.LookupEntry(bgTypeId_))
87 {
88 LOG_ERROR("network", "Battleground: invalid bgtype ({}) received. possible cheater? player {}", bgTypeId_, _player->GetGUID().ToString());
89 return;
90 }
91
92 // chosen battleground type is disabled
94 {
96 return;
97 }
98
99 LOG_DEBUG("network", "WORLD: Recvd CMSG_BATTLEMASTER_JOIN Message from {}", guid.ToString());
100
101 // get queue typeid and random typeid to check if already queued for them
102 BattlegroundTypeId bgTypeId = BattlegroundTypeId(bgTypeId_);
103 BattlegroundQueueTypeId bgQueueTypeId = BattlegroundMgr::BGQueueTypeId(bgTypeId, 0);
105
106 // safety check - bgQueueTypeId == BATTLEGROUND_QUEUE_NONE if tried to queue for arena using this function
107 if (bgQueueTypeId == BATTLEGROUND_QUEUE_NONE)
108 return;
109
110 // ignore if player is already in BG
111 if (_player->InBattleground())
112 return;
113
114 // get bg instance or bg template if instance not found
115 Battleground* bg = nullptr;
116 if (instanceId)
117 bg = sBattlegroundMgr->GetBattlegroundThroughClientInstance(instanceId, bgTypeId);
118
119 if (!bg)
120 bg = sBattlegroundMgr->GetBattlegroundTemplate(bgTypeId);
121
122 if (!bg)
123 return;
124
125 // expected bracket entry
127 if (!bracketEntry)
128 return;
129
130 // must have free queue slot
132 {
133 WorldPacket data;
134 sBattlegroundMgr->BuildGroupJoinedBattlegroundPacket(&data, ERR_BATTLEGROUND_TOO_MANY_QUEUES);
135 SendPacket(&data);
136 return;
137 }
138
139 // queue result (default ok)
141
142 if (!sScriptMgr->CanJoinInBattlegroundQueue(_player, guid, bgTypeId, joinAsGroup, err) && err <= 0)
143 {
144 WorldPacket data;
145 sBattlegroundMgr->BuildGroupJoinedBattlegroundPacket(&data, err);
146 SendPacket(&data);
147 return;
148 }
149
150 BattlegroundQueue& bgQueue = sBattlegroundMgr->GetBattlegroundQueue(bgQueueTypeId);
151
152 // check if player can queue:
153 if (!joinAsGroup)
154 {
155 lfg::LfgState lfgState = sLFGMgr->GetState(GetPlayer()->GetGUID());
156 if (GetPlayer()->InBattleground()) // currently in battleground
157 {
159 }
160 else if (lfgState > lfg::LFG_STATE_NONE && (lfgState != lfg::LFG_STATE_QUEUED || !sWorld->getBoolConfig(CONFIG_ALLOW_JOIN_BG_AND_LFG))) // using lfg system
161 {
163 }
164 else if (!_player->CanJoinToBattleground()) // has deserter debuff
165 {
167 }
168 else if (_player->InBattlegroundQueueForBattlegroundQueueType(bgQueueTypeIdRandom)) // queued for random bg, so can't queue for anything else
169 {
170 err = ERR_IN_RANDOM_BG;
171 }
172 else if (_player->InBattlegroundQueueForBattlegroundQueueType(bgQueueTypeId)) // queued for this bg
173 {
175 }
176 else if (_player->InBattlegroundQueue() && bgTypeId == BATTLEGROUND_RB) // already in queue, so can't queue for random
177 {
179 }
182 _player->InBattlegroundQueueForBattlegroundQueueType(BATTLEGROUND_QUEUE_5v5)) // can't be already queued for arenas
183 {
185 }
186 // don't let Death Knights join BG queues when they are not allowed to be teleported yet
188 {
190 }
191 else if (!_player->GetBGAccessByLevel(bgTypeId))
192 {
194 }
195
196 if (err <= 0)
197 {
198 WorldPacket data;
199 sBattlegroundMgr->BuildGroupJoinedBattlegroundPacket(&data, err);
200 SendPacket(&data);
201 return;
202 }
203
204 GroupQueueInfo* ginfo = bgQueue.AddGroup(_player, nullptr, bgTypeId, bracketEntry, 0, false, isPremade, 0, 0);
205 uint32 avgWaitTime = bgQueue.GetAverageQueueWaitTime(ginfo);
206 uint32 queueSlot = _player->AddBattlegroundQueueId(bgQueueTypeId);
207
208 // send status packet
209 WorldPacket data;
210 sBattlegroundMgr->BuildBattlegroundStatusPacket(&data, bg, queueSlot, STATUS_WAIT_QUEUE, avgWaitTime, 0, 0, TEAM_NEUTRAL);
211 SendPacket(&data);
212
213 sScriptMgr->OnPlayerJoinBG(_player);
214 }
215 // check if group can queue:
216 else
217 {
218 Group* grp = _player->GetGroup();
219
220 // no group or not a leader
221 if (!grp || grp->GetLeaderGUID() != _player->GetGUID())
222 return;
223
224 grp->DoForAllMembers([&err, bgQueueTypeId, bgQueueTypeIdRandom, bgTypeId](Player* member)
225 {
226 if (member->InBattlegroundQueueForBattlegroundQueueType(bgQueueTypeIdRandom)) // queued for random bg, so can't queue for anything else
227 {
228 err = ERR_IN_RANDOM_BG;
229 }
230 else if (member->InBattlegroundQueue() && bgTypeId == BATTLEGROUND_RB) // already in queue, so can't queue for random
231 {
232 err = ERR_IN_NON_RANDOM_BG;
233 }
236 member->InBattlegroundQueueForBattlegroundQueueType(BATTLEGROUND_QUEUE_5v5)) // can't be already queued for arenas
237 {
238 err = ERR_BATTLEGROUND_QUEUED_FOR_RATED;
239 }
240 else if (member->InBattlegroundQueueForBattlegroundQueueType(bgQueueTypeId)) // queued for this bg
241 {
242 err = ERR_BATTLEGROUND_NONE;
243 }
244 else if (!member->GetBGAccessByLevel(bgTypeId))
245 {
246 err = ERR_BATTLEGROUND_JOIN_TIMED_OUT;
247 }
248
249 if (err < 0)
250 {
251 return;
252 }
253 });
254
255 if (err)
256 {
257 err = grp->CanJoinBattlegroundQueue(bg, bgQueueTypeId, 0, bg->GetMaxPlayersPerTeam(), false, 0);
258 }
259
260 if (err <= 0)
261 {
262 grp->DoForAllMembers([err](Player* member)
263 {
264 WorldPacket data;
265 sBattlegroundMgr->BuildGroupJoinedBattlegroundPacket(&data, err);
266 member->GetSession()->SendPacket(&data);
267 });
268
269 return;
270 }
271
272 isPremade = (grp->GetMembersCount() >= bg->GetMinPlayersPerTeam() && bgTypeId != BATTLEGROUND_RB);
273 uint32 avgWaitTime = 0;
274
275 GroupQueueInfo* ginfo = bgQueue.AddGroup(_player, grp, bgTypeId, bracketEntry, 0, false, isPremade, 0, 0);
276 avgWaitTime = bgQueue.GetAverageQueueWaitTime(ginfo);
277
278 grp->DoForAllMembers([bg, err, bgQueueTypeId, avgWaitTime](Player* member)
279 {
280 WorldPacket data;
281
282 // send status packet
283 sBattlegroundMgr->BuildBattlegroundStatusPacket(&data, bg, member->AddBattlegroundQueueId(bgQueueTypeId), STATUS_WAIT_QUEUE, avgWaitTime, 0, 0, TEAM_NEUTRAL);
284 member->GetSession()->SendPacket(&data);
285
286 sBattlegroundMgr->BuildGroupJoinedBattlegroundPacket(&data, err);
287 member->GetSession()->SendPacket(&data);
288
289 sScriptMgr->OnPlayerJoinBG(member);
290 });
291 }
292
293 sBattlegroundMgr->ScheduleQueueUpdate(0, 0, bgQueueTypeId, bgTypeId, bracketEntry->GetBracketId());
294}
@ LANG_BG_DISABLED
Definition: Language.h:718
@ CLASS_CONTEXT_TELEPORT
Definition: UnitDefines.h:207
@ ERR_IN_NON_RANDOM_BG
Definition: SharedDefines.h:3652
@ ERR_BATTLEGROUND_NONE
Definition: SharedDefines.h:3638
@ ERR_BATTLEGROUND_TOO_MANY_QUEUES
Definition: SharedDefines.h:3641
@ ERR_IN_RANDOM_BG
Definition: SharedDefines.h:3651
@ ERR_BATTLEGROUND_QUEUED_FOR_RATED
Definition: SharedDefines.h:3643
@ CLASS_DEATH_KNIGHT
Definition: SharedDefines.h:146
@ BATTLEGROUND_QUEUE_2v2
Definition: SharedDefines.h:3628
@ BATTLEGROUND_QUEUE_5v5
Definition: SharedDefines.h:3630
@ BATTLEGROUND_QUEUE_3v3
Definition: SharedDefines.h:3629
uint32 GetMinPlayersPerTeam() const
Definition: Battleground.h:350
uint32 GetMaxPlayersPerTeam() const
Definition: Battleground.h:349
bool InBattlegroundQueueForBattlegroundQueueType(BattlegroundQueueTypeId bgQueueTypeId) const
Definition: Player.cpp:12238
bool IsGameMaster() const
Definition: Player.h:1158
bool HasSpell(uint32 spell) const override
Definition: Player.cpp:3859
uint32 GetMembersCount() const
Definition: Group.h:245

References _player, Player::AddBattlegroundQueueId(), BattlegroundQueue::AddGroup(), BATTLEGROUND_QUEUE_2v2, BATTLEGROUND_QUEUE_3v3, BATTLEGROUND_QUEUE_5v5, BATTLEGROUND_QUEUE_NONE, BATTLEGROUND_RB, BattlegroundMgr::BGQueueTypeId(), Group::CanJoinBattlegroundQueue(), Player::CanJoinToBattleground(), CLASS_CONTEXT_TELEPORT, CLASS_DEATH_KNIGHT, CONFIG_ALLOW_JOIN_BG_AND_LFG, DISABLE_TYPE_BATTLEGROUND, Group::DoForAllMembers(), ERR_BATTLEGROUND_NONE, ERR_BATTLEGROUND_NOT_IN_BATTLEGROUND, ERR_BATTLEGROUND_QUEUED_FOR_RATED, ERR_BATTLEGROUND_TOO_MANY_QUEUES, ERR_GROUP_JOIN_BATTLEGROUND_DESERTERS, ERR_IN_NON_RANDOM_BG, ERR_IN_RANDOM_BG, ERR_LFG_CANT_USE_BATTLEGROUND, BattlegroundQueue::GetAverageQueueWaitTime(), GetBattlegroundBracketByLevel(), Player::GetBGAccessByLevel(), Battleground::GetBgTypeID(), PvPDifficultyEntry::GetBracketId(), Player::GetGroup(), Object::GetGUID(), Group::GetLeaderGUID(), Unit::GetLevel(), Battleground::GetMapId(), WorldLocation::GetMapId(), Battleground::GetMaxPlayersPerTeam(), Group::GetMembersCount(), Battleground::GetMinPlayersPerTeam(), GetPlayer(), Player::GetSession(), Player::HasFreeBattlegroundQueueId(), Player::HasSpell(), Player::InBattleground(), Player::InBattlegroundQueue(), Player::InBattlegroundQueueForBattlegroundQueueType(), Player::IsClass(), DisableMgr::IsDisabledFor(), Player::IsGameMaster(), LANG_BG_DISABLED, lfg::LFG_STATE_NONE, lfg::LFG_STATE_QUEUED, LOG_DEBUG, LOG_ERROR, ChatHandler::PSendSysMessage(), sBattlegroundMgr, sBattlemasterListStore, SendPacket(), sLFGMgr, sScriptMgr, STATUS_WAIT_QUEUE, sWorld, TEAM_NEUTRAL, and ObjectGuid::ToString().

Referenced by OpcodeTable::Initialize().

◆ HandleBeginTradeOpcode()

void WorldSession::HandleBeginTradeOpcode ( WorldPacket recvPacket)
520{
521 TradeData* my_trade = _player->m_trade;
522 if (!my_trade)
523 return;
524
527}
@ TRADE_STATUS_OPEN_WINDOW
Definition: SharedDefines.h:3552

References _player, Player::GetSession(), TradeData::GetTrader(), Player::m_trade, SendTradeStatus(), and TRADE_STATUS_OPEN_WINDOW.

Referenced by OpcodeTable::Initialize().

◆ HandleBfEntryInviteResponse()

void WorldSession::HandleBfEntryInviteResponse ( WorldPacket recvData)
115{
116 uint32 BattleId;
117 uint8 Accepted;
118
119 recvData >> BattleId >> Accepted;
120
121 Battlefield* Bf = sBattlefieldMgr->GetBattlefieldByBattleId(BattleId);
122 if (!Bf)
123 return;
124
125 //If player accept invitation
126 if (Accepted)
127 {
129 }
130 else
131 {
132 if (_player->GetZoneId() == Bf->GetZoneId())
134 }
135}
void KickPlayerFromBattlefield(ObjectGuid guid)
Kick player from battlefield and teleport him to kick-point location.
Definition: Battlefield.cpp:326
void PlayerAcceptInviteToWar(Player *player)
Definition: Battlefield.cpp:415
uint32 GetZoneId()
Definition: Battlefield.h:242

References _player, Object::GetGUID(), Battlefield::GetZoneId(), WorldObject::GetZoneId(), Battlefield::KickPlayerFromBattlefield(), Battlefield::PlayerAcceptInviteToWar(), and sBattlefieldMgr.

Referenced by OpcodeTable::Initialize().

◆ HandleBfExitRequest()

void WorldSession::HandleBfExitRequest ( WorldPacket recvData)
138{
139 uint32 BattleId;
140
141 recvData >> BattleId;
142
143 Battlefield* Bf = sBattlefieldMgr->GetBattlefieldByBattleId(BattleId);
144 if (!Bf)
145 return;
146
148}
void AskToLeaveQueue(Player *player)
Definition: Battlefield.cpp:401

References _player, Battlefield::AskToLeaveQueue(), and sBattlefieldMgr.

Referenced by OpcodeTable::Initialize().

◆ HandleBfQueueInviteResponse()

void WorldSession::HandleBfQueueInviteResponse ( WorldPacket recvData)
97{
98 uint32 BattleId;
99 uint8 Accepted;
100
101 recvData >> BattleId >> Accepted;
102
103 Battlefield* Bf = sBattlefieldMgr->GetBattlefieldByBattleId(BattleId);
104 if (!Bf)
105 return;
106
107 if (Accepted)
108 {
110 }
111}
void PlayerAcceptInviteToQueue(Player *player)
Definition: Battlefield.cpp:392

References _player, Battlefield::PlayerAcceptInviteToQueue(), and sBattlefieldMgr.

Referenced by OpcodeTable::Initialize().

◆ HandleBinderActivateOpcode()

void WorldSession::HandleBinderActivateOpcode ( WorldPacket recvPacket)
419{
420 ObjectGuid npcGUID;
421 recvData >> npcGUID;
422
423 if (!GetPlayer()->IsInWorld() || !GetPlayer()->IsAlive())
424 return;
425
427 if (!unit)
428 {
429 LOG_DEBUG("network", "WORLD: HandleBinderActivateOpcode - Unit ({}) not found or you can not interact with him.", npcGUID.ToString());
430 return;
431 }
432
433 // remove fake death
434 if (GetPlayer()->HasUnitState(UNIT_STATE_DIED))
436
437 SendBindPoint(unit);
438}
@ UNIT_NPC_FLAG_INNKEEPER
Definition: UnitDefines.h:310
void SendBindPoint(Creature *npc)
Definition: NPCHandler.cpp:440

References Player::GetNPCIfCanInteractWith(), GetPlayer(), LOG_DEBUG, Unit::RemoveAurasByType(), SendBindPoint(), SPELL_AURA_FEIGN_DEATH, ObjectGuid::ToString(), UNIT_NPC_FLAG_INNKEEPER, and UNIT_STATE_DIED.

Referenced by OpcodeTable::Initialize().

◆ HandleBugOpcode()

void WorldSession::HandleBugOpcode ( WorldPacket recvPacket)
618{
619 uint32 suggestion, contentlen, typelen;
620 std::string content, type;
621
622 recv_data >> suggestion >> contentlen >> content;
623
624 recv_data >> typelen >> type;
625
627
628 stmt->SetData(0, type);
629 stmt->SetData(1, content);
630
631 CharacterDatabase.Execute(stmt);
632}
@ CHAR_INS_BUG_REPORT
Definition: CharacterDatabase.h:277

References CHAR_INS_BUG_REPORT, CharacterDatabase, and PreparedStatementBase::SetData().

Referenced by OpcodeTable::Initialize().

◆ HandleBusyTradeOpcode()

void WorldSession::HandleBusyTradeOpcode ( WorldPacket recvPacket)
78{
79 LOG_DEBUG("network", "WORLD: Busy Trade {}", _player->GetGUID().ToString());
80 // recvPacket.print_storage();
81}

References _player, Object::GetGUID(), LOG_DEBUG, and ObjectGuid::ToString().

Referenced by OpcodeTable::Initialize().

◆ HandleBuybackItem()

void WorldSession::HandleBuybackItem ( WorldPacket recvPacket)
910{
911 ObjectGuid vendorguid;
912 uint32 slot;
913
914 recvData >> vendorguid >> slot;
915
917 if (!creature)
918 {
919 LOG_DEBUG("network", "WORLD: HandleBuybackItem - Unit ({}) not found or you can not interact with him.", vendorguid.ToString());
921 return;
922 }
923
924 // remove fake death
925 if (GetPlayer()->HasUnitState(UNIT_STATE_DIED))
927
928 Item* pItem = _player->GetItemFromBuyBackSlot(slot);
929 if (pItem)
930 {
932 if (!_player->HasEnoughMoney(price))
933 {
935 return;
936 }
937
938 ItemPosCountVec dest;
939 InventoryResult msg = _player->CanStoreItem(NULL_BAG, NULL_SLOT, dest, pItem, false);
940 if (msg == EQUIP_ERR_OK)
941 {
942 if (sWorld->getBoolConfig(CONFIG_ITEMDELETE_VENDOR))
943 {
945 stmt->SetData(0, _player->GetGUID().GetCounter());
946 stmt->SetData(1, pItem->GetEntry());
947 stmt->SetData(2, pItem->GetCount());
948 CharacterDatabase.Execute(stmt);
949 }
950
951 _player->ModifyMoney(-(int32)price);
953 _player->ItemAddedQuestCheck(pItem->GetEntry(), pItem->GetCount());
954 _player->StoreItem(dest, pItem, true);
955 }
956 else
957 _player->SendEquipError(msg, pItem, nullptr);
958 return;
959 }
960 else
962}
@ CONFIG_ITEMDELETE_VENDOR
Definition: IWorld.h:161
@ UNIT_NPC_FLAG_VENDOR
Definition: UnitDefines.h:301
@ PLAYER_FIELD_BUYBACK_PRICE_1
Definition: UpdateFields.h:372
@ BUYBACK_SLOT_START
Definition: Player.h:724
@ BUY_ERR_CANT_FIND_ITEM
Definition: Item.h:141
@ BUY_ERR_NOT_ENOUGHT_MONEY
Definition: Item.h:143
@ SELL_ERR_CANT_FIND_VENDOR
Definition: Item.h:157
@ CHAR_DEL_RECOVERY_ITEM
Definition: CharacterDatabase.h:509
void RemoveItemFromBuyBackSlot(uint32 slot, bool del)
Definition: PlayerStorage.cpp:3997
void SendSellError(SellResult msg, Creature *creature, ObjectGuid guid, uint32 param)
Definition: PlayerStorage.cpp:4078
Item * GetItemFromBuyBackSlot(uint32 slot)
Definition: PlayerStorage.cpp:3989
void SendBuyError(BuyResult msg, Creature *creature, uint32 item, uint32 param)
Definition: PlayerStorage.cpp:4066

References _player, BUY_ERR_CANT_FIND_ITEM, BUY_ERR_NOT_ENOUGHT_MONEY, BUYBACK_SLOT_START, Player::CanStoreItem(), CHAR_DEL_RECOVERY_ITEM, CharacterDatabase, CONFIG_ITEMDELETE_VENDOR, ObjectGuid::Empty, EQUIP_ERR_OK, Item::GetCount(), ObjectGuid::GetCounter(), Object::GetEntry(), Object::GetGUID(), Player::GetItemFromBuyBackSlot(), Player::GetNPCIfCanInteractWith(), GetPlayer(), Object::GetUInt32Value(), Player::HasEnoughMoney(), Player::ItemAddedQuestCheck(), LOG_DEBUG, Player::ModifyMoney(), NULL_BAG, NULL_SLOT, PLAYER_FIELD_BUYBACK_PRICE_1, Unit::RemoveAurasByType(), Player::RemoveItemFromBuyBackSlot(), SELL_ERR_CANT_FIND_VENDOR, Player::SendBuyError(), Player::SendEquipError(), Player::SendSellError(), PreparedStatementBase::SetData(), SPELL_AURA_FEIGN_DEATH, Player::StoreItem(), sWorld, ObjectGuid::ToString(), UNIT_NPC_FLAG_VENDOR, and UNIT_STATE_DIED.

Referenced by OpcodeTable::Initialize().

◆ HandleBuyBankSlotOpcode()

void WorldSession::HandleBuyBankSlotOpcode ( WorldPackets::Bank::BuyBankSlot buyBankSlot)
144{
146 if (!CanUseBank(buyBankSlot.Banker))
147 {
149 SendPacket(packet.Write());
150 LOG_DEBUG("network", "WORLD: HandleBuyBankSlotOpcode - {} not found or you can't interact with him.", buyBankSlot.Banker.ToString());
151 return;
152 }
153
155
156 // next slot
157 ++slot;
158
159 LOG_INFO("network", "PLAYER: Buy bank bag slot, slot number = {}", slot);
160
161 BankBagSlotPricesEntry const* slotEntry = sBankBagSlotPricesStore.LookupEntry(slot);
162
163 if (!slotEntry)
164 {
166 SendPacket(packet.Write());
167 return;
168 }
169
170 uint32 price = slotEntry->price;
171
172 if (!_player->HasEnoughMoney(price))
173 {
175 SendPacket(packet.Write());
176 return;
177 }
178
180 _player->ModifyMoney(-int32(price));
181
182 packet.Result = ERR_BANKSLOT_OK;
183 SendPacket(packet.Write());
184
186}
#define LOG_INFO(filterType__,...)
Definition: Log.h:164
DBCStorage< BankBagSlotPricesEntry > sBankBagSlotPricesStore(BankBagSlotPricesEntryfmt)
@ ERR_BANKSLOT_NOTBANKER
Definition: Player.h:113
@ ERR_BANKSLOT_FAILED_TOO_MANY
Definition: Player.h:111
@ ERR_BANKSLOT_OK
Definition: Player.h:114
@ ERR_BANKSLOT_INSUFFICIENT_FUNDS
Definition: Player.h:112
@ ACHIEVEMENT_CRITERIA_TYPE_BUY_BANK_SLOT
Definition: DBCEnums.h:159
uint8 GetBankBagSlotCount() const
Definition: Player.h:1265
void SetBankBagSlotCount(uint8 count)
Definition: Player.h:1266
ObjectGuid Banker
Definition: BankPackets.h:57
Definition: BankPackets.h:61
WorldPacket const * Write() override
Definition: BankPackets.cpp:37
uint32 Result
Definition: BankPackets.h:67
Definition: DBCStructure.h:583
uint32 price
Definition: DBCStructure.h:585

References _player, ACHIEVEMENT_CRITERIA_TYPE_BUY_BANK_SLOT, WorldPackets::Bank::BuyBankSlot::Banker, CanUseBank(), ERR_BANKSLOT_FAILED_TOO_MANY, ERR_BANKSLOT_INSUFFICIENT_FUNDS, ERR_BANKSLOT_NOTBANKER, ERR_BANKSLOT_OK, Player::GetBankBagSlotCount(), Player::HasEnoughMoney(), LOG_DEBUG, LOG_INFO, Player::ModifyMoney(), BankBagSlotPricesEntry::price, WorldPackets::Bank::BuyBankSlotResult::Result, sBankBagSlotPricesStore, SendPacket(), Player::SetBankBagSlotCount(), ObjectGuid::ToString(), Player::UpdateAchievementCriteria(), and WorldPackets::Bank::BuyBankSlotResult::Write().

Referenced by OpcodeTable::Initialize().

◆ HandleBuyItemInSlotOpcode()

void WorldSession::HandleBuyItemInSlotOpcode ( WorldPacket recvPacket)
965{
966 ObjectGuid vendorguid, bagguid;
967 uint32 item, slot, count;
968 uint8 bagslot;
969
970 recvData >> vendorguid >> item >> slot >> bagguid >> bagslot >> count;
971
972 // client expects count starting at 1, and we send vendorslot+1 to client already
973 if (slot > 0)
974 --slot;
975 else
976 return; // cheating
977
978 uint8 bag = NULL_BAG; // init for case invalid bagGUID
979
980 // find bag slot by bag guid
981 if (bagguid == _player->GetGUID())
983 else
984 {
986 {
987 if (Bag* pBag = _player->GetBagByPos(i))
988 {
989 if (bagguid == pBag->GetGUID())
990 {
991 bag = i;
992 break;
993 }
994 }
995 }
996 }
997
998 // bag not found, cheating?
999 if (bag == NULL_BAG)
1000 return;
1001
1002 GetPlayer()->BuyItemFromVendorSlot(vendorguid, slot, item, count, bag, bagslot);
1003}
@ INVENTORY_SLOT_BAG_START
Definition: Player.h:699
@ INVENTORY_SLOT_BAG_END
Definition: Player.h:700
Definition: Bag.h:28
Bag * GetBagByPos(uint8 slot) const
Definition: PlayerStorage.cpp:459
bool BuyItemFromVendorSlot(ObjectGuid vendorguid, uint32 vendorslot, uint32 item, uint8 count, uint8 bag, uint8 slot)
Definition: Player.cpp:10708

References _player, Player::BuyItemFromVendorSlot(), Player::GetBagByPos(), Object::GetGUID(), GetPlayer(), INVENTORY_SLOT_BAG_0, INVENTORY_SLOT_BAG_END, INVENTORY_SLOT_BAG_START, and NULL_BAG.

Referenced by OpcodeTable::Initialize().

◆ HandleBuyItemOpcode()

void WorldSession::HandleBuyItemOpcode ( WorldPacket recvPacket)
1006{
1007 ObjectGuid vendorguid;
1008 uint32 item, slot, count;
1009 uint8 unk1;
1010
1011 recvData >> vendorguid >> item >> slot >> count >> unk1;
1012
1013 // client expects count starting at 1, and we send vendorslot+1 to client already
1014 if (slot > 0)
1015 --slot;
1016 else
1017 return; // cheating
1018
1019 GetPlayer()->BuyItemFromVendorSlot(vendorguid, slot, item, count, NULL_BAG, NULL_SLOT);
1020}

References Player::BuyItemFromVendorSlot(), GetPlayer(), NULL_BAG, and NULL_SLOT.

Referenced by OpcodeTable::Initialize().

◆ HandleBuyStableSlot()

void WorldSession::HandleBuyStableSlot ( WorldPacket recvPacket)
733{
734 LOG_DEBUG("network", "WORLD: Recv CMSG_BUY_STABLE_SLOT.");
735 ObjectGuid npcGUID;
736
737 recvData >> npcGUID;
738
739 if (!CheckStableMaster(npcGUID))
740 {
742 return;
743 }
744
745 // remove fake death
746 if (GetPlayer()->HasUnitState(UNIT_STATE_DIED))
748
749 PetStable& petStable = GetPlayer()->GetOrInitPetStable();
750 if (petStable.MaxStabledPets < MAX_PET_STABLES)
751 {
752 StableSlotPricesEntry const* SlotPrice = sStableSlotPricesStore.LookupEntry(petStable.MaxStabledPets + 1);
753 if (_player->HasEnoughMoney(SlotPrice->Price))
754 {
755 ++petStable.MaxStabledPets;
756 _player->ModifyMoney(-int32(SlotPrice->Price));
758 }
759 else
761 }
762 else
764}
@ STABLE_ERR_MONEY
Definition: NPCHandler.cpp:38
@ STABLE_SUCCESS_BUY_SLOT
Definition: NPCHandler.cpp:42
@ STABLE_ERR_STABLE
Definition: NPCHandler.cpp:39
DBCStorage< StableSlotPricesEntry > sStableSlotPricesStore(StableSlotPricesfmt)
constexpr auto MAX_PET_STABLES
Definition: PetDefines.h:36
Definition: PetDefines.h:202
uint32 MaxStabledPets
Definition: PetDefines.h:227
PetStable & GetOrInitPetStable()
Definition: Player.cpp:15587
bool CheckStableMaster(ObjectGuid guid)
Definition: PetHandler.cpp:651
void SendStableResult(uint8 guid)
Definition: NPCHandler.cpp:543
Definition: DBCStructure.h:1902
uint32 Price
Definition: DBCStructure.h:1904

References _player, CheckStableMaster(), Player::GetOrInitPetStable(), GetPlayer(), Player::HasEnoughMoney(), LOG_DEBUG, MAX_PET_STABLES, PetStable::MaxStabledPets, Player::ModifyMoney(), StableSlotPricesEntry::Price, Unit::RemoveAurasByType(), SendStableResult(), SPELL_AURA_FEIGN_DEATH, sStableSlotPricesStore, STABLE_ERR_MONEY, STABLE_ERR_STABLE, STABLE_SUCCESS_BUY_SLOT, and UNIT_STATE_DIED.

Referenced by OpcodeTable::Initialize().

◆ HandleCalendarAddEvent()

void WorldSession::HandleCalendarAddEvent ( WorldPacket recvData)
240{
241 ObjectGuid guid = _player->GetGUID();
242
243 std::string title;
244 std::string description;
245 uint8 type;
246 uint8 repeatable;
247 uint32 maxInvites;
248 int32 dungeonId;
249 uint32 eventPackedTime;
250 uint32 unkPackedTime;
251 uint32 flags;
252
253 recvData >> title >> description >> type >> repeatable >> maxInvites >> dungeonId;
254 recvData.ReadPackedTime(eventPackedTime);
255 recvData.ReadPackedTime(unkPackedTime);
256 recvData >> flags;
257
258 // prevent attacks with non-utf8 chars -> with multiple packets it will hang up the db due to errors.
259 if (!validUtf8String(recvData, title, "create", guid) || title.size() > 31 || !validUtf8String(recvData, description, "create", guid) || description.size() > 255)
260 return;
261
262 // prevent events in the past
263 // To Do: properly handle timezones and remove the "- time_t(86400L)" hack
264 if (time_t(eventPackedTime) < (GameTime::GetGameTime().count() - time_t(86400L)))
265 {
266 recvData.rfinish();
267 sCalendarMgr->SendCalendarCommandResult(guid, CALENDAR_ERROR_EVENT_PASSED);
268 return;
269 }
270
271 // If the event is a guild event, check if the player is in a guild
273 {
274 if (!_player->GetGuildId())
275 {
276 recvData.rfinish();
277 sCalendarMgr->SendCalendarCommandResult(guid, CALENDAR_ERROR_GUILD_PLAYER_NOT_IN_GUILD);
278 return;
279 }
280 }
281
282 // Check if the player reached the max number of events allowed to create
284 {
285 if (sCalendarMgr->GetGuildEvents(_player->GetGuildId()).size() >= CALENDAR_MAX_GUILD_EVENTS)
286 {
287 recvData.rfinish();
288 sCalendarMgr->SendCalendarCommandResult(guid, CALENDAR_ERROR_GUILD_EVENTS_EXCEEDED);
289 return;
290 }
291 }
292 else
293 {
294 if (sCalendarMgr->GetEventsCreatedBy(guid).size() >= CALENDAR_MAX_EVENTS)
295 {
296 recvData.rfinish();
297 sCalendarMgr->SendCalendarCommandResult(guid, CALENDAR_ERROR_EVENTS_EXCEEDED);
298 return;
299 }
300 }
301
303 {
304 recvData.rfinish();
305 sCalendarMgr->SendCalendarCommandResult(guid, CALENDAR_ERROR_INTERNAL);
306 return;
307 }
309
310 CalendarEvent* calendarEvent = new CalendarEvent(sCalendarMgr->GetFreeEventId(), guid, 0, CalendarEventType(type), dungeonId,
311 time_t(eventPackedTime), flags, time_t(unkPackedTime), title, description);
312
313 if (calendarEvent->IsGuildEvent() || calendarEvent->IsGuildAnnouncement())
314 if (Player* creator = ObjectAccessor::FindConnectedPlayer(guid))
315 calendarEvent->SetGuildId(creator->GetGuildId());
316
317 if (calendarEvent->IsGuildAnnouncement())
318 {
319 // 946684800 is 01/01/2000 00:00:00 - default response time
320 CalendarInvite* invite = new CalendarInvite(0, calendarEvent->GetEventId(), ObjectGuid::Empty, guid, 946684800, CALENDAR_STATUS_NOT_SIGNED_UP, CALENDAR_RANK_PLAYER, "");
321 sCalendarMgr->AddInvite(calendarEvent, invite);
322 }
323 else
324 {
325 uint32 inviteCount;
329
330 memset(status, 0, sizeof(status));
331 memset(rank, 0, sizeof(rank));
332
333 try
334 {
335 recvData >> inviteCount;
336
337 for (uint32 i = 0; i < inviteCount && i < CALENDAR_MAX_INVITES; ++i)
338 {
339 recvData >> invitee[i].ReadAsPacked();
340 recvData >> status[i] >> rank[i];
341 }
342 }
343 catch (ByteBufferException const&)
344 {
345 delete calendarEvent;
346 calendarEvent = nullptr;
347 throw;
348 }
349
351 if (inviteCount > 1)
352 trans = CharacterDatabase.BeginTransaction();
353
354 for (uint32 i = 0; i < inviteCount && i < CALENDAR_MAX_INVITES; ++i)
355 {
356 // 946684800 is 01/01/2000 00:00:00 - default response time
357 CalendarInvite* invite = new CalendarInvite(sCalendarMgr->GetFreeInviteId(), calendarEvent->GetEventId(), invitee[i], guid, 946684800, CalendarInviteStatus(status[i]), CalendarModerationRank(rank[i]), "");
358 sCalendarMgr->AddInvite(calendarEvent, invite, trans);
359 }
360
361 if (inviteCount > 1)
362 CharacterDatabase.CommitTransaction(trans);
363 }
364
365 sCalendarMgr->AddEvent(calendarEvent, CALENDAR_SENDTYPE_ADD);
366}
bool validUtf8String(WorldPacket &recvData, std::string &s, std::string action, ObjectGuid playerGUID)
Definition: CalendarHandler.cpp:227
#define sCalendarMgr
Definition: CalendarMgr.h:344
@ CALENDAR_ERROR_INTERNAL
Definition: CalendarMgr.h:98
@ CALENDAR_ERROR_EVENT_PASSED
Definition: CalendarMgr.h:109
@ CALENDAR_ERROR_EVENTS_EXCEEDED
Definition: CalendarMgr.h:92
@ CALENDAR_ERROR_GUILD_EVENTS_EXCEEDED
Definition: CalendarMgr.h:91
@ CALENDAR_ERROR_GUILD_PLAYER_NOT_IN_GUILD
Definition: CalendarMgr.h:99
CalendarModerationRank
Definition: CalendarMgr.h:44
@ CALENDAR_RANK_PLAYER
Definition: CalendarMgr.h:45
@ CALENDAR_SENDTYPE_ADD
Definition: CalendarMgr.h:53
CalendarEventType
Definition: CalendarMgr.h:58
CalendarInviteStatus
Definition: CalendarMgr.h:75
@ CALENDAR_STATUS_NOT_SIGNED_UP
Definition: CalendarMgr.h:83
@ CALENDAR_MAX_EVENTS
Definition: CalendarMgr.h:128
@ CALENDAR_MAX_INVITES
Definition: CalendarMgr.h:130
@ CALENDAR_MAX_GUILD_EVENTS
Definition: CalendarMgr.h:129
@ CALENDAR_CREATE_EVENT_COOLDOWN
Definition: CalendarMgr.h:131
Definition: CalendarMgr.h:136
Definition: CalendarMgr.h:195
bool IsGuildAnnouncement() const
Definition: CalendarMgr.h:253
void SetGuildId(uint32 guildId)
Definition: CalendarMgr.h:228
bool IsGuildEvent() const
Definition: CalendarMgr.h:252
uint64 GetEventId() const
Definition: CalendarMgr.h:223
uint32 GetGuildId() const
Definition: Player.h:1883
time_t GetCalendarEventCreationCooldown() const
Definition: WorldSession.h:530
void SetCalendarEventCreationCooldown(time_t cooldown)
Definition: WorldSession.h:531
Definition: ByteBuffer.h:32
uint32 ReadPackedTime()
Definition: ByteBuffer.cpp:95

References _player, CALENDAR_CREATE_EVENT_COOLDOWN, CALENDAR_ERROR_EVENT_PASSED, CALENDAR_ERROR_EVENTS_EXCEEDED, CALENDAR_ERROR_GUILD_EVENTS_EXCEEDED, CALENDAR_ERROR_GUILD_PLAYER_NOT_IN_GUILD, CALENDAR_ERROR_INTERNAL, CALENDAR_MAX_EVENTS, CALENDAR_MAX_GUILD_EVENTS, CALENDAR_MAX_INVITES, CALENDAR_RANK_PLAYER, CALENDAR_SENDTYPE_ADD, CALENDAR_STATUS_NOT_SIGNED_UP, CharacterDatabase, ObjectGuid::Empty, ObjectAccessor::FindConnectedPlayer(), GetCalendarEventCreationCooldown(), CalendarEvent::GetEventId(), GameTime::GetGameTime(), Object::GetGUID(), Player::GetGuildId(), CalendarEvent::IsGuildAnnouncement(), CalendarEvent::IsGuildEvent(), ObjectGuid::ReadAsPacked(), ByteBuffer::ReadPackedTime(), ByteBuffer::rfinish(), sCalendarMgr, SetCalendarEventCreationCooldown(), CalendarEvent::SetGuildId(), and validUtf8String().

Referenced by OpcodeTable::Initialize().

◆ HandleCalendarArenaTeam()

void WorldSession::HandleCalendarArenaTeam ( WorldPacket recvData)
217{
218 LOG_DEBUG("network", "CMSG_CALENDAR_ARENA_TEAM [{}]", _player->GetGUID().ToString());
219
220 uint32 arenaTeamId;
221 recvData >> arenaTeamId;
222
223 if (ArenaTeam* team = sArenaTeamMgr->GetArenaTeamById(arenaTeamId))
224 team->MassInviteToEvent(this);
225}

References _player, Object::GetGUID(), LOG_DEBUG, sArenaTeamMgr, and ObjectGuid::ToString().

Referenced by OpcodeTable::Initialize().

◆ HandleCalendarComplain()

void WorldSession::HandleCalendarComplain ( WorldPacket recvData)
767{
768 ObjectGuid guid = _player->GetGUID();
769 uint64 eventId;
770 ObjectGuid complainGUID;
771
772 recvData >> eventId >> complainGUID;
773 LOG_DEBUG("network", "CMSG_CALENDAR_COMPLAIN [{}] EventId [{}] guid [{}]", guid.ToString(), eventId, complainGUID.ToString());
774
775 // what to do with complains?
776}

References _player, Object::GetGUID(), LOG_DEBUG, and ObjectGuid::ToString().

Referenced by OpcodeTable::Initialize().

◆ HandleCalendarCopyEvent()

void WorldSession::HandleCalendarCopyEvent ( WorldPacket recvData)
437{
438 ObjectGuid guid = _player->GetGUID();
439 uint64 eventId;
440 uint64 inviteId;
441 uint32 eventTime;
442
443 recvData >> eventId >> inviteId;
444 recvData.ReadPackedTime(eventTime);
445 LOG_DEBUG("network", "CMSG_CALENDAR_COPY_EVENT [{}], EventId [{}] inviteId [{}] Time: {}", guid.ToString(), eventId, inviteId, eventTime);
446
447 // prevent events in the past
448 // To Do: properly handle timezones and remove the "- time_t(86400L)" hack
449 if (time_t(eventTime) < (GameTime::GetGameTime().count() - time_t(86400L)))
450 {
451 recvData.rfinish();
452 sCalendarMgr->SendCalendarCommandResult(guid, CALENDAR_ERROR_EVENT_PASSED);
453 return;
454 }
455
456 if (CalendarEvent* oldEvent = sCalendarMgr->GetEvent(eventId))
457 {
458 // Ensure that the player has access to the event
459 if (oldEvent->IsGuildEvent() || oldEvent->IsGuildAnnouncement())
460 {
461 if (oldEvent->GetGuildId() != _player->GetGuildId())
462 {
463 sCalendarMgr->SendCalendarCommandResult(guid, CALENDAR_ERROR_EVENT_INVALID);
464 return;
465 }
466 }
467 else
468 {
469 if (oldEvent->GetCreatorGUID() != guid)
470 {
471 sCalendarMgr->SendCalendarCommandResult(guid, CALENDAR_ERROR_EVENT_INVALID);
472 return;
473 }
474 }
475
476 // Check if the player reached the max number of events allowed to create
477 if (oldEvent->IsGuildEvent() || oldEvent->IsGuildAnnouncement())
478 {
479 if (sCalendarMgr->GetGuildEvents(_player->GetGuildId()).size() >= CALENDAR_MAX_GUILD_EVENTS)
480 {
481 sCalendarMgr->SendCalendarCommandResult(guid, CALENDAR_ERROR_GUILD_EVENTS_EXCEEDED);
482 return;
483 }
484 }
485 else
486 {
487 if (sCalendarMgr->GetEventsCreatedBy(guid).size() >= CALENDAR_MAX_EVENTS)
488 {
489 sCalendarMgr->SendCalendarCommandResult(guid, CALENDAR_ERROR_EVENTS_EXCEEDED);
490 return;
491 }
492 }
493
495 {
496 sCalendarMgr->SendCalendarCommandResult(guid, CALENDAR_ERROR_INTERNAL);
497 return;
498 }
500
501 CalendarEvent* newEvent = new CalendarEvent(*oldEvent, sCalendarMgr->GetFreeEventId());
502 newEvent->SetEventTime(time_t(eventTime));
503 sCalendarMgr->AddEvent(newEvent, CALENDAR_SENDTYPE_COPY);
504
505 CalendarInviteStore invites = sCalendarMgr->GetEventInvites(eventId);
507 if (invites.size() > 1)
508 trans = CharacterDatabase.BeginTransaction();
509
510 for (CalendarInviteStore::const_iterator itr = invites.begin(); itr != invites.end(); ++itr)
511 sCalendarMgr->AddInvite(newEvent, new CalendarInvite(**itr, sCalendarMgr->GetFreeInviteId(), newEvent->GetEventId()), trans);
512
513 if (invites.size() > 1)
514 CharacterDatabase.CommitTransaction(trans);
515 // should we change owner when somebody makes a copy of event owned by another person?
516 }
517 else
518 sCalendarMgr->SendCalendarCommandResult(guid, CALENDAR_ERROR_EVENT_INVALID);
519}
@ CALENDAR_ERROR_EVENT_INVALID
Definition: CalendarMgr.h:96
std::vector< CalendarInvite * > CalendarInviteStore
Definition: CalendarMgr.h:273
@ CALENDAR_SENDTYPE_COPY
Definition: CalendarMgr.h:54
void SetEventTime(time_t eventTime)
Definition: CalendarMgr.h:243

References _player, CALENDAR_CREATE_EVENT_COOLDOWN, CALENDAR_ERROR_EVENT_INVALID, CALENDAR_ERROR_EVENT_PASSED, CALENDAR_ERROR_EVENTS_EXCEEDED, CALENDAR_ERROR_GUILD_EVENTS_EXCEEDED, CALENDAR_ERROR_INTERNAL, CALENDAR_MAX_EVENTS, CALENDAR_MAX_GUILD_EVENTS, CALENDAR_SENDTYPE_COPY, CharacterDatabase, GetCalendarEventCreationCooldown(), CalendarEvent::GetEventId(), GameTime::GetGameTime(), Object::GetGUID(), Player::GetGuildId(), LOG_DEBUG, ByteBuffer::ReadPackedTime(), ByteBuffer::rfinish(), sCalendarMgr, SetCalendarEventCreationCooldown(), CalendarEvent::SetEventTime(), and ObjectGuid::ToString().

Referenced by OpcodeTable::Initialize().

◆ HandleCalendarEventInvite()

void WorldSession::HandleCalendarEventInvite ( WorldPacket recvData)
522{
523 LOG_DEBUG("network", "CMSG_CALENDAR_EVENT_INVITE");
524
525 ObjectGuid playerGuid = _player->GetGUID();
526
527 uint64 eventId;
528 uint64 inviteId;
529 std::string name;
530 bool isPreInvite;
531 bool isGuildEvent;
532
533 ObjectGuid inviteeGuid;
534 uint32 inviteeTeamId = TEAM_NEUTRAL;
535 uint32 inviteeGuildId = 0;
536
537 recvData >> eventId >> inviteId >> name >> isPreInvite >> isGuildEvent;
538
539 if (Player* player = ObjectAccessor::FindPlayerByName(name.c_str(), false))
540 {
541 // Invitee is online
542 inviteeGuid = player->GetGUID();
543 inviteeTeamId = player->GetTeamId();
544 inviteeGuildId = player->GetGuildId();
545 }
546 else
547 {
548 // xinef: Get Data From global storage
549 if (ObjectGuid guid = sCharacterCache->GetCharacterGuidByName(name))
550 {
551 if (CharacterCacheEntry const* playerData = sCharacterCache->GetCharacterCacheByGuid(guid))
552 {
553 inviteeGuid = guid;
554 inviteeTeamId = Player::TeamIdForRace(playerData->Race);
555 inviteeGuildId = playerData->GuildId;
556 }
557 }
558 }
559
560 if (!inviteeGuid)
561 {
562 sCalendarMgr->SendCalendarCommandResult(playerGuid, CALENDAR_ERROR_PLAYER_NOT_FOUND);
563 return;
564 }
565
566 if (_player->GetTeamId() != inviteeTeamId && !sWorld->getBoolConfig(CONFIG_ALLOW_TWO_SIDE_INTERACTION_CALENDAR))
567 {
568 sCalendarMgr->SendCalendarCommandResult(playerGuid, CALENDAR_ERROR_NOT_ALLIED);
569 return;
570 }
571
572 // xinef: sync query
573 if (QueryResult result = CharacterDatabase.Query("SELECT flags FROM character_social WHERE guid = {} AND friend = {}", inviteeGuid.GetCounter(), playerGuid.GetCounter()))
574 {
575 Field* fields = result->Fetch();
576 if (fields[0].Get<uint8>() & SOCIAL_FLAG_IGNORED)
577 {
578 sCalendarMgr->SendCalendarCommandResult(playerGuid, CALENDAR_ERROR_IGNORING_YOU_S, name.c_str());
579 return;
580 }
581 }
582
583 if (!isPreInvite)
584 {
585 if (CalendarEvent* calendarEvent = sCalendarMgr->GetEvent(eventId))
586 {
587 if (calendarEvent->IsGuildEvent() && calendarEvent->GetGuildId() == inviteeGuildId)
588 {
589 // we can't invite guild members to guild events
590 sCalendarMgr->SendCalendarCommandResult(playerGuid, CALENDAR_ERROR_NO_GUILD_INVITES);
591 return;
592 }
593
594 // 946684800 is 01/01/2000 00:00:00 - default response time
595 CalendarInvite* invite = new CalendarInvite(sCalendarMgr->GetFreeInviteId(), eventId, inviteeGuid, playerGuid, 946684800, CALENDAR_STATUS_INVITED, CALENDAR_RANK_PLAYER, "");
596 sCalendarMgr->AddInvite(calendarEvent, invite);
597 }
598 else
599 sCalendarMgr->SendCalendarCommandResult(playerGuid, CALENDAR_ERROR_EVENT_INVALID);
600 }
601 else
602 {
603 if (isGuildEvent && inviteeGuildId == _player->GetGuildId())
604 {
605 sCalendarMgr->SendCalendarCommandResult(playerGuid, CALENDAR_ERROR_NO_GUILD_INVITES);
606 return;
607 }
608
609 // 946684800 is 01/01/2000 00:00:00 - default response time
610 CalendarInvite* invite = new CalendarInvite(inviteId, 0, inviteeGuid, playerGuid, 946684800, CALENDAR_STATUS_INVITED, CALENDAR_RANK_PLAYER, "");
611 sCalendarMgr->SendCalendarEventInvite(*invite);
612 }
613}
@ CALENDAR_ERROR_NOT_ALLIED
Definition: CalendarMgr.h:102
@ CALENDAR_ERROR_NO_GUILD_INVITES
Definition: CalendarMgr.h:121
@ CALENDAR_ERROR_IGNORING_YOU_S
Definition: CalendarMgr.h:103
@ CALENDAR_ERROR_PLAYER_NOT_FOUND
Definition: CalendarMgr.h:101
@ CALENDAR_STATUS_INVITED
Definition: CalendarMgr.h:76
@ CONFIG_ALLOW_TWO_SIDE_INTERACTION_CALENDAR
Definition: IWorld.h:72
std::shared_ptr< ResultSet > QueryResult
Definition: DatabaseEnvFwd.h:27
Class used to access individual fields of database query result.
Definition: Field.h:98

References _player, CALENDAR_ERROR_EVENT_INVALID, CALENDAR_ERROR_IGNORING_YOU_S, CALENDAR_ERROR_NO_GUILD_INVITES, CALENDAR_ERROR_NOT_ALLIED, CALENDAR_ERROR_PLAYER_NOT_FOUND, CALENDAR_RANK_PLAYER, CALENDAR_STATUS_INVITED, CharacterDatabase, CONFIG_ALLOW_TWO_SIDE_INTERACTION_CALENDAR, ObjectAccessor::FindPlayerByName(), ObjectGuid::GetCounter(), Object::GetGUID(), Player::GetGuildId(), Player::GetTeamId(), LOG_DEBUG, sCalendarMgr, sCharacterCache, SOCIAL_FLAG_IGNORED, sWorld, TEAM_NEUTRAL, and Player::TeamIdForRace().

Referenced by OpcodeTable::Initialize().

◆ HandleCalendarEventModeratorStatus()

void WorldSession::HandleCalendarEventModeratorStatus ( WorldPacket recvData)
738{
739 ObjectGuid guid = _player->GetGUID();
740 ObjectGuid invitee;
741 uint64 eventId;
742 uint64 inviteId;
743 uint64 ownerInviteId; // isn't it sender's inviteId?
744 uint8 rank;
745
746 recvData>> invitee.ReadAsPacked();
747 recvData >> eventId >> inviteId >> ownerInviteId >> rank;
748 LOG_DEBUG("network", "CMSG_CALENDAR_EVENT_MODERATOR_STATUS [{}] EventId [{}] ownerInviteId [{}], Invitee ([{}] id: [{}], rank {}",
749 guid.ToString(), eventId, ownerInviteId, invitee.ToString(), inviteId, rank);
750
751 if (CalendarEvent* calendarEvent = sCalendarMgr->GetEvent(eventId))
752 {
753 if (CalendarInvite* invite = sCalendarMgr->GetInvite(inviteId))
754 {
755 invite->SetRank(CalendarModerationRank(rank));
756 sCalendarMgr->UpdateInvite(invite);
757 sCalendarMgr->SendCalendarEventModeratorStatusAlert(*calendarEvent, *invite);
758 }
759 else
760 sCalendarMgr->SendCalendarCommandResult(guid, CALENDAR_ERROR_NO_INVITE); // correct?
761 }
762 else
763 sCalendarMgr->SendCalendarCommandResult(guid, CALENDAR_ERROR_EVENT_INVALID);
764}
@ CALENDAR_ERROR_NO_INVITE
Definition: CalendarMgr.h:117

References _player, CALENDAR_ERROR_EVENT_INVALID, CALENDAR_ERROR_NO_INVITE, Object::GetGUID(), LOG_DEBUG, ObjectGuid::ReadAsPacked(), sCalendarMgr, and ObjectGuid::ToString().

Referenced by OpcodeTable::Initialize().

◆ HandleCalendarEventRemoveInvite()

void WorldSession::HandleCalendarEventRemoveInvite ( WorldPacket recvData)
678{
679 ObjectGuid guid = _player->GetGUID();
680 ObjectGuid invitee;
681 uint64 eventId;
682 uint64 ownerInviteId; // isn't it sender's inviteId?
683 uint64 inviteId;
684
685 recvData>> invitee.ReadAsPacked();
686 recvData >> inviteId >> ownerInviteId >> eventId;
687
688 LOG_DEBUG("network", "CMSG_CALENDAR_EVENT_REMOVE_INVITE [{}] EventId [{}], ownerInviteId [{}], Invitee ([{}] id: [{}])",
689 guid.ToString(), eventId, ownerInviteId, invitee.ToString(), inviteId);
690
691 if (CalendarEvent* calendarEvent = sCalendarMgr->GetEvent(eventId))
692 {
693 if (calendarEvent->GetCreatorGUID() == invitee)
694 {
695 sCalendarMgr->SendCalendarCommandResult(guid, CALENDAR_ERROR_DELETE_CREATOR_FAILED);
696 return;
697 }
698
699 sCalendarMgr->RemoveInvite(inviteId, eventId, guid);
700 }
701 else
702 sCalendarMgr->SendCalendarCommandResult(guid, CALENDAR_ERROR_NO_INVITE);
703}
@ CALENDAR_ERROR_DELETE_CREATOR_FAILED
Definition: CalendarMgr.h:111

References _player, CALENDAR_ERROR_DELETE_CREATOR_FAILED, CALENDAR_ERROR_NO_INVITE, Object::GetGUID(), LOG_DEBUG, ObjectGuid::ReadAsPacked(), sCalendarMgr, and ObjectGuid::ToString().

Referenced by OpcodeTable::Initialize().

◆ HandleCalendarEventRsvp()

void WorldSession::HandleCalendarEventRsvp ( WorldPacket recvData)
642{
643 ObjectGuid guid = _player->GetGUID();
644 uint64 eventId;
645 uint64 inviteId;
646 uint32 status;
647
648 recvData >> eventId >> inviteId >> status;
649 LOG_DEBUG("network", "CMSG_CALENDAR_EVENT_RSVP [{}] EventId [{}], InviteId [{}], status {}",
650 guid.ToString(), eventId, inviteId, status);
651
652 if (CalendarEvent* calendarEvent = sCalendarMgr->GetEvent(eventId))
653 {
654 // i think we still should be able to remove self from locked events
655 if (status != CALENDAR_STATUS_REMOVED && calendarEvent->GetFlags() & CALENDAR_FLAG_INVITES_LOCKED)
656 {
657 sCalendarMgr->SendCalendarCommandResult(guid, CALENDAR_ERROR_EVENT_LOCKED);
658 return;
659 }
660
661 if (CalendarInvite* invite = sCalendarMgr->GetInvite(inviteId))
662 {
663 invite->SetStatus(CalendarInviteStatus(status));
664 invite->SetStatusTime(GameTime::GetGameTime().count());
665
666 sCalendarMgr->UpdateInvite(invite);
667 sCalendarMgr->SendCalendarEventStatus(*calendarEvent, *invite);
668 sCalendarMgr->SendCalendarClearPendingAction(guid);
669 }
670 else
671 sCalendarMgr->SendCalendarCommandResult(guid, CALENDAR_ERROR_NO_INVITE); // correct?
672 }
673 else
674 sCalendarMgr->SendCalendarCommandResult(guid, CALENDAR_ERROR_EVENT_INVALID);
675}
@ CALENDAR_ERROR_EVENT_LOCKED
Definition: CalendarMgr.h:110
@ CALENDAR_FLAG_INVITES_LOCKED
Definition: CalendarMgr.h:38
@ CALENDAR_STATUS_REMOVED
Definition: CalendarMgr.h:85

References _player, CALENDAR_ERROR_EVENT_INVALID, CALENDAR_ERROR_EVENT_LOCKED, CALENDAR_ERROR_NO_INVITE, CALENDAR_FLAG_INVITES_LOCKED, CALENDAR_STATUS_REMOVED, GameTime::GetGameTime(), Object::GetGUID(), LOG_DEBUG, sCalendarMgr, and ObjectGuid::ToString().

Referenced by OpcodeTable::Initialize().

◆ HandleCalendarEventSignup()

void WorldSession::HandleCalendarEventSignup ( WorldPacket recvData)
616{
617 ObjectGuid guid = _player->GetGUID();
618 uint64 eventId;
619 bool tentative;
620
621 recvData >> eventId >> tentative;
622 LOG_DEBUG("network", "CMSG_CALENDAR_EVENT_SIGNUP [{}] EventId [{}] Tentative {}", guid.ToString(), eventId, tentative);
623
624 if (CalendarEvent* calendarEvent = sCalendarMgr->GetEvent(eventId))
625 {
626 if (calendarEvent->IsGuildEvent() && calendarEvent->GetGuildId() != _player->GetGuildId())
627 {
628 sCalendarMgr->SendCalendarCommandResult(guid, CALENDAR_ERROR_GUILD_PLAYER_NOT_IN_GUILD);
629 return;
630 }
631
633 CalendarInvite* invite = new CalendarInvite(sCalendarMgr->GetFreeInviteId(), eventId, guid, guid, GameTime::GetGameTime().count(), status, CALENDAR_RANK_PLAYER, "");
634 sCalendarMgr->AddInvite(calendarEvent, invite);
635 sCalendarMgr->SendCalendarClearPendingAction(guid);
636 }
637 else
638 sCalendarMgr->SendCalendarCommandResult(guid, CALENDAR_ERROR_EVENT_INVALID);
639}
@ CALENDAR_STATUS_TENTATIVE
Definition: CalendarMgr.h:84
@ CALENDAR_STATUS_SIGNED_UP
Definition: CalendarMgr.h:82

References _player, CALENDAR_ERROR_EVENT_INVALID, CALENDAR_ERROR_GUILD_PLAYER_NOT_IN_GUILD, CALENDAR_RANK_PLAYER, CALENDAR_STATUS_SIGNED_UP, CALENDAR_STATUS_TENTATIVE, GameTime::GetGameTime(), Object::GetGUID(), Player::GetGuildId(), LOG_DEBUG, sCalendarMgr, and ObjectGuid::ToString().

Referenced by OpcodeTable::Initialize().

◆ HandleCalendarEventStatus()

void WorldSession::HandleCalendarEventStatus ( WorldPacket recvData)
706{
707 ObjectGuid guid = _player->GetGUID();
708 ObjectGuid invitee;
709 uint64 eventId;
710 uint64 inviteId;
711 uint64 ownerInviteId; // isn't it sender's inviteId?
712 uint8 status;
713
714 recvData >> invitee.ReadAsPacked();
715 recvData >> eventId >> inviteId >> ownerInviteId >> status;
716 LOG_DEBUG("network", "CMSG_CALENDAR_EVENT_STATUS [{}] EventId [{}] ownerInviteId [{}], Invitee ({}) id: [{}], status {}",
717 guid.ToString(), eventId, ownerInviteId, invitee.ToString(), inviteId, status);
718
719 if (CalendarEvent* calendarEvent = sCalendarMgr->GetEvent(eventId))
720 {
721 if (CalendarInvite* invite = sCalendarMgr->GetInvite(inviteId))
722 {
723 invite->SetStatus((CalendarInviteStatus)status);
724 invite->SetStatusTime(GameTime::GetGameTime().count());
725
726 sCalendarMgr->UpdateInvite(invite);
727 sCalendarMgr->SendCalendarEventStatus(*calendarEvent, *invite);
728 sCalendarMgr->SendCalendarClearPendingAction(invitee);
729 }
730 else
731 sCalendarMgr->SendCalendarCommandResult(guid, CALENDAR_ERROR_NO_INVITE); // correct?
732 }
733 else
734 sCalendarMgr->SendCalendarCommandResult(guid, CALENDAR_ERROR_EVENT_INVALID);
735}

References _player, CALENDAR_ERROR_EVENT_INVALID, CALENDAR_ERROR_NO_INVITE, GameTime::GetGameTime(), Object::GetGUID(), LOG_DEBUG, ObjectGuid::ReadAsPacked(), sCalendarMgr, and ObjectGuid::ToString().

Referenced by OpcodeTable::Initialize().

◆ HandleCalendarGetCalendar()

void WorldSession::HandleCalendarGetCalendar ( WorldPacket recvData)
Todo:
: Fix this, how we do know how many and what holidays to send?
53{
54 ObjectGuid guid = _player->GetGUID();
55 LOG_DEBUG("network", "CMSG_CALENDAR_GET_CALENDAR [{}]", guid.ToString());
56
57 time_t currTime = GameTime::GetGameTime().count();
58
59 WorldPacket data(SMSG_CALENDAR_SEND_CALENDAR, 1000); // Average size if no instance
60
61 CalendarInviteStore invites = sCalendarMgr->GetPlayerInvites(guid);
62 data << uint32(invites.size());
63 for (CalendarInviteStore::const_iterator itr = invites.begin(); itr != invites.end(); ++itr)
64 {
65 data << uint64((*itr)->GetEventId());
66 data << uint64((*itr)->GetInviteId());
67 data << uint8((*itr)->GetStatus());
68 data << uint8((*itr)->GetRank());
69
70 if (CalendarEvent* calendarEvent = sCalendarMgr->GetEvent((*itr)->GetEventId()))
71 {
72 data << uint8(calendarEvent->IsGuildEvent());
73 data << calendarEvent->GetCreatorGUID().WriteAsPacked();
74 }
75 else
76 {
77 data << uint8(0);
78 data << (*itr)->GetSenderGUID().WriteAsPacked();
79 }
80 }
81
82 CalendarEventStore playerEvents = sCalendarMgr->GetPlayerEvents(guid);
83 data << uint32(playerEvents.size());
84 for (CalendarEventStore::const_iterator itr = playerEvents.begin(); itr != playerEvents.end(); ++itr)
85 {
86 CalendarEvent* calendarEvent = *itr;
87
88 data << uint64(calendarEvent->GetEventId());
89 data << calendarEvent->GetTitle();
90 data << uint32(calendarEvent->GetType());
91 data.AppendPackedTime(calendarEvent->GetEventTime());
92 data << uint32(calendarEvent->GetFlags());
93 data << int32(calendarEvent->GetDungeonId());
94 data << calendarEvent->GetCreatorGUID().WriteAsPacked();
95 }
96
97 data << uint32(currTime); // server time
98 data.AppendPackedTime(currTime); // zone time
99
100 ByteBuffer dataBuffer;
101 uint32 boundCounter = 0;
102 for (uint8 i = 0; i < MAX_DIFFICULTY; ++i)
103 {
104 BoundInstancesMap const& m_boundInstances = sInstanceSaveMgr->PlayerGetBoundInstances(_player->GetGUID(), Difficulty(i));
105 for (BoundInstancesMap::const_iterator itr = m_boundInstances.begin(); itr != m_boundInstances.end(); ++itr)
106 {
107 if (itr->second.perm)
108 {
109 InstanceSave const* save = itr->second.save;
110 time_t resetTime = itr->second.extended ? save->GetExtendedResetTime() : save->GetResetTime();
111 dataBuffer << uint32(save->GetMapId());
112 dataBuffer << uint32(save->GetDifficulty());
113 dataBuffer << uint32(resetTime >= currTime ? resetTime - currTime : 0);
114 dataBuffer << ObjectGuid::Create<HighGuid::Instance>(save->GetInstanceId()); // instance save id as unique instance copy id
115 ++boundCounter;
116 }
117 }
118 }
119
120 data << uint32(boundCounter);
121 data.append(dataBuffer);
122
123 // pussywizard
124 uint32 relationTime = sWorld->getIntConfig(CONFIG_INSTANCE_RESET_TIME_RELATIVE_TIMESTAMP) + sWorld->getIntConfig(CONFIG_INSTANCE_RESET_TIME_HOUR) * HOUR; // set point in time (default 29.12.2005) + X hours
125 data << uint32(relationTime);
126
127 // Reuse variables
128 boundCounter = 0;
129 std::set<uint32> sentMaps;
130 dataBuffer.clear();
131
132 ResetTimeByMapDifficultyMap const& resets = sInstanceSaveMgr->GetResetTimeMap();
133 for (ResetTimeByMapDifficultyMap::const_iterator itr = resets.begin(); itr != resets.end(); ++itr)
134 {
135 uint32 mapId = PAIR32_LOPART(itr->first);
136 if (sentMaps.find(mapId) != sentMaps.end())
137 continue;
138
139 MapEntry const* mapEntry = sMapStore.LookupEntry(mapId);
140 if (!mapEntry || !mapEntry->IsRaid())
141 continue;
142
143 sentMaps.insert(mapId);
144
145 dataBuffer << int32(mapId);
146 time_t period = sInstanceSaveMgr->GetExtendedResetTimeFor(mapId, (Difficulty)PAIR32_HIPART(itr->first)) - itr->second;
147 dataBuffer << int32(period); // pussywizard: reset time period
148 dataBuffer << int32(0); // pussywizard: reset time offset, needed for other than 7-day periods if not aligned with relationTime
149 ++boundCounter;
150 }
151
152 data << uint32(boundCounter);
153 data.append(dataBuffer);
154
156 data << uint32(sGameEventMgr->modifiedHolidays.size());
157 for (uint32 entry : sGameEventMgr->modifiedHolidays)
158 {
159 HolidaysEntry const* holiday = sHolidaysStore.LookupEntry(entry);
160
161 if (DisableMgr::IsDisabledFor(DISABLE_TYPE_GAME_EVENT, sGameEventMgr->GetHolidayEventId(holiday->Id), nullptr))
162 {
163 continue;
164 }
165
166 data << uint32(holiday->Id); // m_ID
167 data << uint32(holiday->Region); // m_region, might be looping
168 data << uint32(holiday->Looping); // m_looping, might be region
169 data << uint32(holiday->Priority); // m_priority
170 data << uint32(holiday->CalendarFilterType); // m_calendarFilterType
171
172 for (uint8 j = 0; j < MAX_HOLIDAY_DATES; ++j)
173 data << uint32(holiday->Date[j]); // 26 * m_date -- WritePackedTime ?
174
175 for (uint8 j = 0; j < MAX_HOLIDAY_DURATIONS; ++j)
176 data << uint32(holiday->Duration[j]); // 10 * m_duration
177
178 for (uint8 j = 0; j < MAX_HOLIDAY_FLAGS; ++j)
179 data << uint32(holiday->CalendarFlags[j]); // 10 * m_calendarFlags
180
181 data << holiday->TextureFilename; // m_textureFilename (holiday name)
182 }
183
184 SendPacket(&data);
185}
constexpr auto HOUR
Definition: Common.h:48
@ DISABLE_TYPE_GAME_EVENT
Definition: DisableMgr.h:38
std::unordered_map< uint32, InstancePlayerBind > BoundInstancesMap
Definition: InstanceSaveMgr.h:46
#define sInstanceSaveMgr
Definition: InstanceSaveMgr.h:202
std::unordered_map< uint32, time_t > ResetTimeByMapDifficultyMap
Definition: InstanceSaveMgr.h:104
#define sGameEventMgr
Definition: GameEventMgr.h:186
std::unordered_set< CalendarEvent * > CalendarEventStore
Definition: CalendarMgr.h:274
DBCStorage< HolidaysEntry > sHolidaysStore(Holidaysfmt)
DBCStorage< MapEntry > sMapStore(MapEntryfmt)
@ CONFIG_INSTANCE_RESET_TIME_RELATIVE_TIMESTAMP
Definition: IWorld.h:249
@ CONFIG_INSTANCE_RESET_TIME_HOUR
Definition: IWorld.h:248
uint16 PAIR32_HIPART(uint32 x)
Definition: ObjectDefines.h:92
uint16 PAIR32_LOPART(uint32 x)
Definition: ObjectDefines.h:97
#define MAX_HOLIDAY_FLAGS
Definition: DBCStructure.h:1120
#define MAX_HOLIDAY_DURATIONS
Definition: DBCStructure.h:1118
#define MAX_HOLIDAY_DATES
Definition: DBCStructure.h:1119
Difficulty
Definition: DBCEnums.h:266
#define MAX_DIFFICULTY
Definition: DBCEnums.h:283
@ SMSG_CALENDAR_SEND_CALENDAR
Definition: Opcodes.h:1108
ObjectGuid GetCreatorGUID() const
Definition: CalendarMgr.h:226
CalendarEventType GetType() const
Definition: CalendarMgr.h:238
int32 GetDungeonId() const
Definition: CalendarMgr.h:241
std::string GetTitle() const
Definition: CalendarMgr.h:232
time_t GetEventTime() const
Definition: CalendarMgr.h:244
uint32 GetFlags() const
Definition: CalendarMgr.h:247
PackedGuid WriteAsPacked() const
Definition: ObjectGuid.h:316
Definition: InstanceSaveMgr.h:56
time_t GetExtendedResetTime() const
Definition: InstanceSaveMgr.h:76
uint32 GetInstanceId() const
Definition: InstanceSaveMgr.h:61
uint32 GetMapId() const
Definition: InstanceSaveMgr.h:62
Difficulty GetDifficulty() const
Definition: InstanceSaveMgr.h:63
time_t GetResetTime() const
Definition: InstanceSaveMgr.h:75
Definition: DBCStructure.h:1123
int32 CalendarFilterType
Definition: DBCStructure.h:1134
uint32 Duration[MAX_HOLIDAY_DURATIONS]
Definition: DBCStructure.h:1125
uint32 Id
Definition: DBCStructure.h:1124
char const * TextureFilename
Definition: DBCStructure.h:1132
uint32 Priority
Definition: DBCStructure.h:1133
uint32 CalendarFlags[MAX_HOLIDAY_FLAGS]
Definition: DBCStructure.h:1129
uint32 Region
Definition: DBCStructure.h:1127
uint32 Date[MAX_HOLIDAY_DATES]
Definition: DBCStructure.h:1126
uint32 Looping
Definition: DBCStructure.h:1128
Definition: DBCStructure.h:1324
bool IsRaid() const
Definition: DBCStructure.h:1353
Definition: ByteBuffer.h:70
void clear()
Definition: ByteBuffer.h:122

References _player, ByteBuffer::append(), ByteBuffer::AppendPackedTime(), HolidaysEntry::CalendarFilterType, HolidaysEntry::CalendarFlags, ByteBuffer::clear(), CONFIG_INSTANCE_RESET_TIME_HOUR, CONFIG_INSTANCE_RESET_TIME_RELATIVE_TIMESTAMP, HolidaysEntry::Date, DISABLE_TYPE_GAME_EVENT, HolidaysEntry::Duration, CalendarEvent::GetCreatorGUID(), InstanceSave::GetDifficulty(), CalendarEvent::GetDungeonId(), CalendarEvent::GetEventId(), CalendarEvent::GetEventTime(), InstanceSave::GetExtendedResetTime(), CalendarEvent::GetFlags(), GameTime::GetGameTime(), Object::GetGUID(), InstanceSave::GetInstanceId(), InstanceSave::GetMapId(), InstanceSave::GetResetTime(), CalendarEvent::GetTitle(), CalendarEvent::GetType(), HOUR, HolidaysEntry::Id, DisableMgr::IsDisabledFor(), MapEntry::IsRaid(), LOG_DEBUG, HolidaysEntry::Looping, MAX_DIFFICULTY, MAX_HOLIDAY_DATES, MAX_HOLIDAY_DURATIONS, MAX_HOLIDAY_FLAGS, PAIR32_HIPART(), PAIR32_LOPART(), HolidaysEntry::Priority, HolidaysEntry::Region, sCalendarMgr, SendPacket(), sGameEventMgr, sHolidaysStore, sInstanceSaveMgr, sMapStore, SMSG_CALENDAR_SEND_CALENDAR, sWorld, HolidaysEntry::TextureFilename, ObjectGuid::ToString(), and ObjectGuid::WriteAsPacked().

Referenced by OpcodeTable::Initialize().

◆ HandleCalendarGetEvent()

void WorldSession::HandleCalendarGetEvent ( WorldPacket recvData)
188{
189 uint64 eventId;
190 recvData >> eventId;
191
192 LOG_DEBUG("network", "CMSG_CALENDAR_GET_EVENT. Player [{}] Event [{}]", _player->GetGUID().ToString(), eventId);
193
194 if (CalendarEvent* calendarEvent = sCalendarMgr->GetEvent(eventId))
195 sCalendarMgr->SendCalendarEvent(_player->GetGUID(), *calendarEvent, CALENDAR_SENDTYPE_GET);
196 else
197 sCalendarMgr->SendCalendarCommandResult(_player->GetGUID(), CALENDAR_ERROR_EVENT_INVALID);
198}
@ CALENDAR_SENDTYPE_GET
Definition: CalendarMgr.h:52

References _player, CALENDAR_ERROR_EVENT_INVALID, CALENDAR_SENDTYPE_GET, Object::GetGUID(), LOG_DEBUG, sCalendarMgr, and ObjectGuid::ToString().

Referenced by OpcodeTable::Initialize().

◆ HandleCalendarGetNumPending()

void WorldSession::HandleCalendarGetNumPending ( WorldPacket recvData)
779{
780 ObjectGuid guid = _player->GetGUID();
781 uint32 pending = sCalendarMgr->GetPlayerNumPending(guid);
782
783 LOG_DEBUG("network", "CMSG_CALENDAR_GET_NUM_PENDING: [{}] Pending: {}", guid.ToString(), pending);
784
786 data << uint32(pending);
787 SendPacket(&data);
788}
@ SMSG_CALENDAR_SEND_NUM_PENDING
Definition: Opcodes.h:1126

References _player, Object::GetGUID(), LOG_DEBUG, sCalendarMgr, SendPacket(), SMSG_CALENDAR_SEND_NUM_PENDING, and ObjectGuid::ToString().

Referenced by OpcodeTable::Initialize().

◆ HandleCalendarGuildFilter()

void WorldSession::HandleCalendarGuildFilter ( WorldPacket recvData)
201{
202 LOG_DEBUG("network", "CMSG_CALENDAR_GUILD_FILTER [{}]", _player->GetGUID().ToString());
203
204 uint32 minLevel;
205 uint32 maxLevel;
206 uint32 minRank;
207
208 recvData >> minLevel >> maxLevel >> minRank;
209
210 if (Guild* guild = sGuildMgr->GetGuildById(_player->GetGuildId()))
211 guild->MassInviteToEvent(this, minLevel, maxLevel, minRank);
212
213 LOG_DEBUG("network", "CMSG_CALENDAR_GUILD_FILTER: Min level [{}], Max level [{}], Min rank [{}]", minLevel, maxLevel, minRank);
214}
#define sGuildMgr
Definition: GuildMgr.h:51
Definition: Guild.h:295

References _player, Object::GetGUID(), Player::GetGuildId(), LOG_DEBUG, sGuildMgr, and ObjectGuid::ToString().

Referenced by OpcodeTable::Initialize().

◆ HandleCalendarRemoveEvent()

void WorldSession::HandleCalendarRemoveEvent ( WorldPacket recvData)
426{
427 ObjectGuid guid = _player->GetGUID();
428 uint64 eventId;
429
430 recvData >> eventId;
431 recvData.rfinish(); // Skip flags & invite ID, we don't use them
432
433 sCalendarMgr->RemoveEvent(eventId, guid);
434}

References _player, Object::GetGUID(), ByteBuffer::rfinish(), and sCalendarMgr.

Referenced by OpcodeTable::Initialize().

◆ HandleCalendarUpdateEvent()

void WorldSession::HandleCalendarUpdateEvent ( WorldPacket recvData)
369{
370 ObjectGuid guid = _player->GetGUID();
371 time_t oldEventTime;
372
373 uint64 eventId;
374 uint64 inviteId;
375 std::string title;
376 std::string description;
377 uint8 type;
378 uint8 repetitionType;
379 uint32 maxInvites;
380 int32 dungeonId;
381 uint32 eventPackedTime;
382 uint32 timeZoneTime;
383 uint32 flags;
384
385 recvData >> eventId >> inviteId >> title >> description >> type >> repetitionType >> maxInvites >> dungeonId;
386 recvData.ReadPackedTime(eventPackedTime);
387 recvData.ReadPackedTime(timeZoneTime);
388 recvData >> flags;
389
390 // prevent attacks with non-utf8 chars -> with multiple packets it will hang up the db due to errors.
391 if (!validUtf8String(recvData, title, "update", guid) || title.size() > 31 || !validUtf8String(recvData, description, "update", guid) || description.size() > 255)
392 return;
393
394 // prevent events in the past
395 // To Do: properly handle timezones and remove the "- time_t(86400L)" hack
396 if (time_t(eventPackedTime) < (GameTime::GetGameTime().count() - time_t(86400L)))
397 {
398 recvData.rfinish();
399 return;
400 }
401
402 LOG_DEBUG("network", "CMSG_CALENDAR_UPDATE_EVENT [{}] EventId [{}], InviteId [{}] Title {}, Description {}, type {} "
403 "Repeatable {}, MaxInvites {}, Dungeon ID {}, Time {} Time2 {}, Flags {}",
404 guid.ToString(), eventId, inviteId, title, description, type, repetitionType, maxInvites, dungeonId, eventPackedTime, timeZoneTime, flags);
405
406 if (CalendarEvent* calendarEvent = sCalendarMgr->GetEvent(eventId))
407 {
408 oldEventTime = calendarEvent->GetEventTime();
409
410 calendarEvent->SetType(CalendarEventType(type));
411 calendarEvent->SetFlags(flags);
412 calendarEvent->SetEventTime(time_t(eventPackedTime));
413 calendarEvent->SetTimeZoneTime(time_t(timeZoneTime)); // Not sure, seems constant from the little sniffs we have
414 calendarEvent->SetDungeonId(dungeonId);
415 calendarEvent->SetTitle(title);
416 calendarEvent->SetDescription(description);
417
418 sCalendarMgr->UpdateEvent(calendarEvent);
419 sCalendarMgr->SendCalendarEventUpdateAlert(*calendarEvent, oldEventTime);
420 }
421 else
422 sCalendarMgr->SendCalendarCommandResult(guid, CALENDAR_ERROR_EVENT_INVALID);
423}

References _player, CALENDAR_ERROR_EVENT_INVALID, GameTime::GetGameTime(), Object::GetGUID(), LOG_DEBUG, ByteBuffer::ReadPackedTime(), ByteBuffer::rfinish(), sCalendarMgr, ObjectGuid::ToString(), and validUtf8String().

Referenced by OpcodeTable::Initialize().

◆ HandleCancelAuraOpcode()

void WorldSession::HandleCancelAuraOpcode ( WorldPacket recvPacket)
492{
493 uint32 spellId;
494 recvPacket >> spellId;
495
496 SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(spellId);
497 if (!spellInfo)
498 return;
499
500 // not allow remove spells with attr SPELL_ATTR0_NO_AURA_CANCEL
502 {
503 return;
504 }
505
506 // channeled spell case (it currently casted then)
507 if (spellInfo->IsChanneled())
508 {
510 if (curSpell->m_spellInfo->Id == spellId)
512 return;
513 }
514
515 // non channeled case:
516 // don't allow remove non positive spells
517 // don't allow cancelling passive auras (some of them are visible)
518 if (!spellInfo->IsPositive() || spellInfo->IsPassive())
519 {
520 return;
521 }
522
523 // maybe should only remove one buff when there are multiple?
525}
@ CURRENT_CHANNELED_SPELL
Definition: Unit.h:539
@ AURA_REMOVE_BY_CANCEL
Definition: SpellAuraDefines.h:393
@ SPELL_ATTR0_NO_AURA_CANCEL
Definition: SharedDefines.h:413
void RemoveOwnedAura(AuraMap::iterator &i, AuraRemoveMode removeMode=AURA_REMOVE_BY_DEFAULT)
Definition: Unit.cpp:4686
void InterruptSpell(CurrentSpellTypes spellType, bool withDelayed=true, bool withInstant=true, bool bySelf=false)
Definition: Unit.cpp:4043
Spell * GetCurrentSpell(CurrentSpellTypes spellType) const
Definition: Unit.h:1468
bool IsPassive() const
Definition: SpellInfo.cpp:1097
bool IsChanneled() const
Definition: SpellInfo.cpp:1255
bool HasAttribute(SpellAttr0 attribute) const
Definition: SpellInfo.h:415
bool IsPositive() const
Definition: SpellInfo.cpp:1236

References _player, AURA_REMOVE_BY_CANCEL, CURRENT_CHANNELED_SPELL, ObjectGuid::Empty, Unit::GetCurrentSpell(), SpellInfo::HasAttribute(), Unit::InterruptSpell(), SpellInfo::IsChanneled(), SpellInfo::IsPassive(), SpellInfo::IsPositive(), Unit::RemoveOwnedAura(), SPELL_ATTR0_NO_AURA_CANCEL, and sSpellMgr.

Referenced by OpcodeTable::Initialize().

◆ HandleCancelAutoRepeatSpellOpcode()

void WorldSession::HandleCancelAutoRepeatSpellOpcode ( WorldPacket recvPacket)
570{
571 // may be better send SMSG_CANCEL_AUTO_REPEAT?
572 // cancel and prepare for deleting
574}
@ CURRENT_AUTOREPEAT_SPELL
Definition: Unit.h:540

References _player, CURRENT_AUTOREPEAT_SPELL, and Unit::InterruptSpell().

Referenced by OpcodeTable::Initialize().

◆ HandleCancelCastOpcode()

void WorldSession::HandleCancelCastOpcode ( WorldPacket recvPacket)
480{
481 uint32 spellId;
482
483 recvPacket.read_skip<uint8>(); // counter, increments with every CANCEL packet, don't use for now
484 recvPacket >> spellId;
485
487 if (_player->IsNonMeleeSpellCast(false))
488 _player->InterruptNonMeleeSpells(false, spellId, false, true);
489}
@ CURRENT_MELEE_SPELL
Definition: Unit.h:537
void InterruptNonMeleeSpells(bool withDelayed, uint32 spellid=0, bool withInstant=true, bool bySelf=false)
Definition: Unit.cpp:4110
bool IsNonMeleeSpellCast(bool withDelayed, bool skipChanneled=false, bool skipAutorepeat=false, bool isAutoshoot=false, bool skipInstant=true) const
Definition: Unit.cpp:4080

References _player, CURRENT_MELEE_SPELL, Unit::InterruptNonMeleeSpells(), Unit::InterruptSpell(), Unit::IsNonMeleeSpellCast(), and ByteBuffer::read_skip().

Referenced by OpcodeTable::Initialize().

◆ HandleCancelChanneling()

void WorldSession::HandleCancelChanneling ( WorldPacket recvData)
577{
578 uint32 spellID = 0;
579 recvData >> spellID;
580
581 // ignore for remote control state (for player case)
582 Unit* mover = _player->m_mover;
583 if (!mover)
584 {
585 return;
586 }
587
588 SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(spellID);
589 if (!spellInfo)
590 {
591 return;
592 }
593
594 // not allow remove spells with attr SPELL_ATTR0_NO_AURA_CANCEL
596 {
597 return;
598 }
599
601 if (!spell || spell->GetSpellInfo()->Id != spellInfo->Id)
602 {
603 return;
604 }
605
607}
SafeUnitPointer m_mover
Definition: Player.h:2315
SpellInfo const * GetSpellInfo() const
Definition: Spell.h:575
uint32 Id
Definition: SpellInfo.h:320

References _player, CURRENT_CHANNELED_SPELL, Unit::GetCurrentSpell(), Spell::GetSpellInfo(), SpellInfo::HasAttribute(), SpellInfo::Id, Unit::InterruptSpell(), Player::m_mover, SPELL_ATTR0_NO_AURA_CANCEL, and sSpellMgr.

Referenced by OpcodeTable::Initialize().

◆ HandleCancelGrowthAuraOpcode()

void WorldSession::HandleCancelGrowthAuraOpcode ( WorldPacket recvPacket)
566{
567}

Referenced by OpcodeTable::Initialize().

◆ HandleCancelMountAuraOpcode()

void WorldSession::HandleCancelMountAuraOpcode ( WorldPacket recvData)
1539{
1540 LOG_DEBUG("network", "WORLD: CMSG_CANCEL_MOUNT_AURA");
1541
1542 //If player is not mounted, so go out :)
1543 if (!_player->IsMounted()) // not blizz like; no any messages on blizz
1544 {
1546 return;
1547 }
1548
1549 if (_player->IsInFlight()) // not blizz like; no any messages on blizz
1550 {
1552 return;
1553 }
1554
1555 _player->Dismount();
1557}
@ LANG_CHAR_NON_MOUNTED
Definition: Language.h:54
@ LANG_YOU_IN_FLIGHT
Definition: Language.h:50
@ SPELL_AURA_MOUNTED
Definition: SpellAuraDefines.h:141
virtual void SendSysMessage(std::string_view str, bool escapeCharacters=false)
Definition: Chat.cpp:159
void Dismount()
Definition: Unit.cpp:13488
bool IsMounted() const
Definition: Unit.h:990

References _player, Unit::Dismount(), Unit::IsInFlight(), Unit::IsMounted(), LANG_CHAR_NON_MOUNTED, LANG_YOU_IN_FLIGHT, LOG_DEBUG, Unit::RemoveAurasByType(), ChatHandler::SendSysMessage(), and SPELL_AURA_MOUNTED.

Referenced by OpcodeTable::Initialize().

◆ HandleCancelTempEnchantmentOpcode()

void WorldSession::HandleCancelTempEnchantmentOpcode ( WorldPacket recvData)
1600{
1601 LOG_DEBUG("network", "WORLD: CMSG_CANCEL_TEMP_ENCHANTMENT");
1602
1603 uint32 eslot;
1604
1605 recvData >> eslot;
1606
1607 // apply only to equipped item
1609 return;
1610
1612
1613 if (!item)
1614 return;
1615
1617 return;
1618
1621}
@ TEMP_ENCHANTMENT_SLOT
Definition: Item.h:170
uint32 GetEnchantmentId(EnchantmentSlot slot) const
Definition: Item.h:304
void ClearEnchantment(EnchantmentSlot slot)
Definition: Item.cpp:961

References Player::ApplyEnchantment(), Item::ClearEnchantment(), Item::GetEnchantmentId(), Player::GetItemByPos(), GetPlayer(), INVENTORY_SLOT_BAG_0, Player::IsEquipmentPos(), LOG_DEBUG, and TEMP_ENCHANTMENT_SLOT.

Referenced by OpcodeTable::Initialize().

◆ HandleCancelTradeOpcode()

void WorldSession::HandleCancelTradeOpcode ( WorldPacket recvPacket)
538{
539 // sended also after LOGOUT COMPLETE
540 if (_player) // needed because STATUS_LOGGEDIN_OR_RECENTLY_LOGGOUT
541 _player->TradeCancel(true);
542}
void TradeCancel(bool sendback)
Definition: PlayerStorage.cpp:4090

References _player, and Player::TradeCancel().

Referenced by OpcodeTable::Initialize().

◆ HandleCastSpellOpcode()

void WorldSession::HandleCastSpellOpcode ( WorldPacket recvPacket)
Todo:
: Preparation for #23204
341{
342 uint32 spellId;
343 uint8 castCount, castFlags;
344 recvPacket >> castCount >> spellId >> castFlags;
345 TriggerCastFlags triggerFlag = TRIGGERED_NONE;
346
347 uint32 oldSpellId = spellId;
348
349 LOG_DEBUG("network", "WORLD: got cast spell packet, castCount: {}, spellId: {}, castFlags: {}, data length = {}", castCount, spellId, castFlags, (uint32)recvPacket.size());
350
351 // ignore for remote control state (for player case)
352 Unit* mover = _player->m_mover;
353 if (mover != _player && mover->IsPlayer())
354 {
355 recvPacket.rfinish(); // prevent spam at ignore packet
356 return;
357 }
358
359 SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(spellId);
360
361 if (!spellInfo)
362 {
363 LOG_ERROR("network.opcode", "WORLD: unknown spell id {}", spellId);
364 recvPacket.rfinish(); // prevent spam at ignore packet
365 return;
366 }
367
368 // client provided targets
369 SpellCastTargets targets;
370 targets.Read(recvPacket, mover);
371 HandleClientCastFlags(recvPacket, castFlags, targets);
372
373 // not have spell in spellbook
374 if (mover->IsPlayer())
375 {
376 // not have spell in spellbook or spell passive and not casted by client
377 if (!(spellInfo->Targets & TARGET_FLAG_GAMEOBJECT_ITEM) && (!mover->ToPlayer()->HasActiveSpell(spellId) || spellInfo->IsPassive()))
378 {
379 bool allow = false;
380
381 // allow casting of unknown spells for special lock cases
382 if (GameObject* go = targets.GetGOTarget())
383 {
384 if (go->GetSpellForLock(mover->ToPlayer()) == spellInfo)
385 {
386 allow = true;
387 }
388 }
389
391 // allow casting of spells triggered by clientside periodic trigger auras
392 /*
393 if (caster->HasAuraTypeWithTriggerSpell(SPELL_AURA_PERIODIC_TRIGGER_SPELL_FROM_CLIENT, spellId))
394 {
395 allow = true;
396 triggerFlag = TRIGGERED_FULL_MASK;
397 }
398 */
399
400 if (!allow)
401 return;
402 }
403 }
404 else
405 {
406 // pussywizard: casting player's spells from vehicle when seat allows it
407 // if ANYTHING CHANGES in this function, INFORM ME BEFORE applying!!!
408 if (Vehicle* veh = mover->GetVehicleKit())
409 if (const VehicleSeatEntry* seat = veh->GetSeatForPassenger(_player))
410 if (seat->m_flags & VEHICLE_SEAT_FLAG_CAN_ATTACK || spellInfo->Effects[EFFECT_0].Effect == SPELL_EFFECT_OPEN_LOCK /*allow looting from vehicle, but only if player has required spell (all necessary opening spells are in playercreateinfo_spell)*/)
411 if ((mover->IsCreature() && !mover->ToCreature()->HasSpell(spellId)) || spellInfo->IsPassive()) // the creature can't cast that spell, check player instead
412 {
413 if (!(spellInfo->Targets & TARGET_FLAG_GAMEOBJECT_ITEM) && (!_player->HasActiveSpell (spellId) || spellInfo->IsPassive()))
414 {
415 //cheater? kick? ban?
416 recvPacket.rfinish(); // prevent spam at ignore packet
417 return;
418 }
419
420 // at this point, player is a valid caster
421 // swapping the mover will stop the check below at IsUnit, so everything works fine
422 mover = _player;
423 }
424
425 // not have spell in spellbook or spell passive and not casted by client
426 if ((mover->IsCreature() && !mover->ToCreature()->HasSpell(spellId)) || spellInfo->IsPassive())
427 {
428 //cheater? kick? ban?
429 recvPacket.rfinish(); // prevent spam at ignore packet
430 return;
431 }
432 }
433
434 sScriptMgr->ValidateSpellAtCastSpell(_player, oldSpellId, spellId, castCount, castFlags);
435
436 if (oldSpellId != spellId)
437 spellInfo = sSpellMgr->GetSpellInfo(spellId);
438
439 // Client is resending autoshot cast opcode when other spell is casted during shoot rotation
440 // Skip it to prevent "interrupt" message
443 {
444 recvPacket.rfinish();
445 return;
446 }
447
448 // can't use our own spells when we're in possession of another unit,
449 if (_player->isPossessing())
450 {
451 return;
452 }
453
454 // pussywizard: HandleClientCastFlags calls HandleMovementOpcodes, which can result in pretty much anything. Caster not in map will crash at GetMap() for spell difficulty in Spell constructor.
455 if (!mover->FindMap())
456 {
457 recvPacket.rfinish(); // prevent spam at ignore packet
458 return;
459 }
460
461 // auto-selection buff level base at target level (in spellInfo)
462 if (targets.GetUnitTarget())
463 {
464 SpellInfo const* actualSpellInfo = spellInfo->GetAuraRankForLevel(targets.GetUnitTarget()->GetLevel());
465
466 // if rank not found then function return nullptr but in explicit cast case original spell can be casted and later failed with appropriate error message
467 if (actualSpellInfo)
468 spellInfo = actualSpellInfo;
469 }
470
471 Spell* spell = new Spell(mover, spellInfo, triggerFlag, ObjectGuid::Empty, false);
472
473 sScriptMgr->ValidateSpellAtCastSpellResult(_player, mover, spell, oldSpellId, spellId);
474
475 spell->m_cast_count = castCount; // set count of casts
476 spell->prepare(&targets);
477}
TriggerCastFlags
Definition: SpellDefines.h:129
@ TRIGGERED_NONE
Definition: SpellDefines.h:130
@ TARGET_FLAG_GAMEOBJECT_ITEM
Definition: SpellInfo.h:60
@ EFFECT_0
Definition: SharedDefines.h:31
@ SPELL_EFFECT_OPEN_LOCK
Definition: SharedDefines.h:811
bool HasSpell(uint32 spellID) const override
Definition: Creature.cpp:2920
bool IsPlayer() const
Definition: Object.h:197
Player * ToPlayer()
Definition: Object.h:198
bool IsCreature() const
Definition: Object.h:201
Creature * ToCreature()
Definition: Object.h:202
Map * FindMap() const
Definition: Object.h:532
bool HasActiveSpell(uint32 spell) const
Definition: Player.cpp:3871
bool isPossessing() const
Definition: Unit.h:1281
Vehicle * GetVehicleKit() const
Definition: Unit.h:1686
void HandleClientCastFlags(WorldPacket &recvPacket, uint8 castFlags, SpellCastTargets &targets)
Definition: SpellHandler.cpp:35
GameObject * GetGOTarget() const
Definition: Spell.cpp:263
void Read(ByteBuffer &data, Unit *caster)
Definition: Spell.cpp:125
Unit * GetUnitTarget() const
Definition: Spell.cpp:231
uint8 m_cast_count
Definition: Spell.h:524
SpellInfo const *const m_spellInfo
Definition: Spell.h:520
SpellInfo const * GetAuraRankForLevel(uint8 level) const
Definition: SpellInfo.cpp:2525
std::array< SpellEffectInfo, MAX_SPELL_EFFECTS > Effects
Definition: SpellInfo.h:393
uint32 Targets
Definition: SpellInfo.h:335
bool IsAutoRepeatRangedSpell() const
Definition: SpellInfo.cpp:1282

References _player, CURRENT_AUTOREPEAT_SPELL, EFFECT_0, SpellInfo::Effects, ObjectGuid::Empty, WorldObject::FindMap(), SpellInfo::GetAuraRankForLevel(), Unit::GetCurrentSpell(), SpellCastTargets::GetGOTarget(), Unit::GetLevel(), SpellCastTargets::GetUnitTarget(), Unit::GetVehicleKit(), HandleClientCastFlags(), Player::HasActiveSpell(), Creature::HasSpell(), SpellInfo::IsAutoRepeatRangedSpell(), Object::IsCreature(), SpellInfo::IsPassive(), Object::IsPlayer(), Unit::isPossessing(), LOG_DEBUG, LOG_ERROR, Spell::m_cast_count, Player::m_mover, Spell::m_spellInfo, Spell::prepare(), SpellCastTargets::Read(), ByteBuffer::rfinish(), ByteBuffer::size(), SPELL_EFFECT_OPEN_LOCK, sScriptMgr, sSpellMgr, TARGET_FLAG_GAMEOBJECT_ITEM, SpellInfo::Targets, Object::ToCreature(), Object::ToPlayer(), TRIGGERED_NONE, and VEHICLE_SEAT_FLAG_CAN_ATTACK.

Referenced by OpcodeTable::Initialize().

◆ HandleChangeSeatsOnControlledVehicle()

void WorldSession::HandleChangeSeatsOnControlledVehicle ( WorldPacket recvData)
59{
60 LOG_DEBUG("network", "WORLD: Recvd CMSG_CHANGE_SEATS_ON_CONTROLLED_VEHICLE");
61
62 Unit* vehicle_base = GetPlayer()->GetVehicleBase();
63 if (!vehicle_base)
64 {
65 recvData.rfinish(); // prevent warnings spam
66 return;
67 }
68
70 if (!seat->CanSwitchFromSeat())
71 {
72 recvData.rfinish(); // prevent warnings spam
73 LOG_ERROR("network.opcode", "HandleChangeSeatsOnControlledVehicle, Opcode: {}, Player {} tried to switch seats but current seatflags {} don't permit that.",
74 recvData.GetOpcode(), GetPlayer()->GetGUID().ToString(), seat->m_flags);
75 return;
76 }
77
78 switch (recvData.GetOpcode())
79 {
81 GetPlayer()->ChangeSeat(-1, false);
82 break;
84 GetPlayer()->ChangeSeat(-1, true);
85 break;
87 {
88 ObjectGuid guid; // current vehicle guid
89 recvData >> guid.ReadAsPacked();
90
91 // pussywizard:
92 if (vehicle_base->GetGUID() != guid)
93 {
94 recvData.rfinish(); // prevent warnings spam
95 return;
96 }
97
98 MovementInfo movementInfo;
99 movementInfo.guid = guid;
100 ReadMovementInfo(recvData, &movementInfo);
101 vehicle_base->m_movementInfo = movementInfo;
102
103 ObjectGuid accessory; // accessory guid
104 recvData >> accessory.ReadAsPacked();
105
106 int8 seatId;
107 recvData >> seatId;
108
109 if (!accessory)
110 GetPlayer()->ChangeSeat(-1, seatId > 0); // prev/next
111 else if (Unit* vehUnit = ObjectAccessor::GetUnit(*GetPlayer(), accessory))
112 {
113 if (Vehicle* vehicle = vehUnit->GetVehicleKit())
114 if (vehicle->HasEmptySeat(seatId))
115 vehUnit->HandleSpellClick(GetPlayer(), seatId);
116 }
117 break;
118 }
120 {
121 ObjectGuid guid; // current vehicle guid
122 recvData >> guid.ReadAsPacked();
123
124 int8 seatId;
125 recvData >> seatId;
126
127 if (vehicle_base->GetGUID() == guid)
128 GetPlayer()->ChangeSeat(seatId);
129 else if (Unit* vehUnit = ObjectAccessor::GetUnit(*GetPlayer(), guid))
130 if (Vehicle* vehicle = vehUnit->GetVehicleKit())
131 if (vehicle->HasEmptySeat(seatId))
132 vehUnit->HandleSpellClick(GetPlayer(), seatId);
133 break;
134 }
135 default:
136 break;
137 }
138}
std::int8_t int8
Definition: Define.h:105
@ CMSG_REQUEST_VEHICLE_SWITCH_SEAT
Definition: Opcodes.h:1175
@ CMSG_REQUEST_VEHICLE_NEXT_SEAT
Definition: Opcodes.h:1174
@ CMSG_REQUEST_VEHICLE_PREV_SEAT
Definition: Opcodes.h:1173
@ CMSG_CHANGE_SEATS_ON_CONTROLLED_VEHICLE
Definition: Opcodes.h:1209
Definition: Object.h:276
ObjectGuid guid
Definition: Object.h:278
Unit * GetVehicleBase() const
Definition: Unit.cpp:18707
void ChangeSeat(int8 seatId, bool next=true)
Definition: Unit.cpp:19681
VehicleSeatEntry const * GetSeatForPassenger(Unit const *passenger)
Definition: Vehicle.cpp:580
void ReadMovementInfo(WorldPacket &data, MovementInfo *mi)
Definition: WorldSession.cpp:959
bool CanSwitchFromSeat() const
Definition: DBCStructure.h:2118

References VehicleSeatEntry::CanSwitchFromSeat(), Unit::ChangeSeat(), CMSG_CHANGE_SEATS_ON_CONTROLLED_VEHICLE, CMSG_REQUEST_VEHICLE_NEXT_SEAT, CMSG_REQUEST_VEHICLE_PREV_SEAT, CMSG_REQUEST_VEHICLE_SWITCH_SEAT, Object::GetGUID(), WorldPacket::GetOpcode(), GetPlayer(), Vehicle::GetSeatForPassenger(), ObjectAccessor::GetUnit(), Unit::GetVehicle(), Unit::GetVehicleBase(), MovementInfo::guid, LOG_DEBUG, LOG_ERROR, VehicleSeatEntry::m_flags, WorldObject::m_movementInfo, ObjectGuid::ReadAsPacked(), ReadMovementInfo(), and ByteBuffer::rfinish().

Referenced by OpcodeTable::Initialize().

◆ HandleChannelAnnouncements()

void WorldSession::HandleChannelAnnouncements ( WorldPacket recvPacket)
255{
256 std::string channelName;
257 recvPacket >> channelName;
258
259 LOG_DEBUG("chat.system", "CMSG_CHANNEL_ANNOUNCEMENTS {} Channel: {}",
260 GetPlayerInfo(), channelName);
262 if (Channel* channel = cMgr->GetChannel(channelName, GetPlayer()))
263 channel->Announce(GetPlayer());
264}
Definition: Channel.h:148
Definition: ChannelMgr.h:30
static ChannelMgr * forTeam(TeamId teamId)
Definition: ChannelMgr.cpp:33

References ChannelMgr::forTeam(), GetPlayer(), GetPlayerInfo(), GetTeamId(), and LOG_DEBUG.

Referenced by OpcodeTable::Initialize().

◆ HandleChannelBan()

void WorldSession::HandleChannelBan ( WorldPacket recvPacket)
225{
226 std::string channelName, targetName;
227 recvPacket >> channelName >> targetName;
228
229 LOG_DEBUG("chat.system", "CMSG_CHANNEL_BAN {} Channel: {}, Target: {}",
230 GetPlayerInfo(), channelName, targetName);
231 if (!normalizePlayerName(targetName))
232 return;
233
235 if (Channel* channel = cMgr->GetChannel(channelName, GetPlayer()))
236 channel->Ban(GetPlayer(), targetName);
237}

References ChannelMgr::forTeam(), GetPlayer(), GetPlayerInfo(), GetTeamId(), LOG_DEBUG, and normalizePlayerName().

Referenced by OpcodeTable::Initialize().

◆ HandleChannelDeclineInvite()

void WorldSession::HandleChannelDeclineInvite ( WorldPacket recvPacket)
816{
817 // used only with EXTRA_LOGS
818 (void)recvPacket;
819
820 LOG_DEBUG("network", "Opcode {}", recvPacket.GetOpcode());
821}

References WorldPacket::GetOpcode(), and LOG_DEBUG.

Referenced by OpcodeTable::Initialize().

◆ HandleChannelDisplayListQuery()

void WorldSession::HandleChannelDisplayListQuery ( WorldPacket recvPacket)
280{
281 // this should be OK because the 2 function _were_ the same
282 HandleChannelList(recvPacket);
283}
void HandleChannelList(WorldPacket &recvPacket)
Definition: ChannelHandler.cpp:79

References HandleChannelList().

Referenced by OpcodeTable::Initialize().

◆ HandleChannelInvite()

void WorldSession::HandleChannelInvite ( WorldPacket recvPacket)
195{
196 std::string channelName, targetName;
197 recvPacket >> channelName >> targetName;
198
199 LOG_DEBUG("chat.system", "CMSG_CHANNEL_INVITE {} Channel: {}, Target: {}",
200 GetPlayerInfo(), channelName, targetName);
201 if (!normalizePlayerName(targetName))
202 return;
203
205 if (Channel* channel = cMgr->GetChannel(channelName, GetPlayer()))
206 channel->Invite(GetPlayer(), targetName);
207}

References ChannelMgr::forTeam(), GetPlayer(), GetPlayerInfo(), GetTeamId(), LOG_DEBUG, and normalizePlayerName().

Referenced by OpcodeTable::Initialize().

◆ HandleChannelKick()

void WorldSession::HandleChannelKick ( WorldPacket recvPacket)
210{
211 std::string channelName, targetName;
212 recvPacket >> channelName >> targetName;
213
214 LOG_DEBUG("chat.system", "CMSG_CHANNEL_KICK {} Channel: {}, Target: {}",
215 GetPlayerInfo(), channelName, targetName);
216 if (!normalizePlayerName(targetName))
217 return;
218
220 if (Channel* channel = cMgr->GetChannel(channelName, GetPlayer()))
221 channel->Kick(GetPlayer(), targetName);
222}

References ChannelMgr::forTeam(), GetPlayer(), GetPlayerInfo(), GetTeamId(), LOG_DEBUG, and normalizePlayerName().

Referenced by OpcodeTable::Initialize().

◆ HandleChannelList()

void WorldSession::HandleChannelList ( WorldPacket recvPacket)
80{
81 std::string channelName;
82 recvPacket >> channelName;
83
84 LOG_DEBUG("chat.system", "{} {} Channel: {}",
85 recvPacket.GetOpcode() == CMSG_CHANNEL_DISPLAY_LIST ? "CMSG_CHANNEL_DISPLAY_LIST" : "CMSG_CHANNEL_LIST",
86 GetPlayerInfo(), channelName);
88 if (Channel* channel = cMgr->GetChannel(channelName, GetPlayer()))
89 channel->List(GetPlayer());
90}
@ CMSG_CHANNEL_DISPLAY_LIST
Definition: Opcodes.h:1008

References CMSG_CHANNEL_DISPLAY_LIST, ChannelMgr::forTeam(), WorldPacket::GetOpcode(), GetPlayer(), GetPlayerInfo(), GetTeamId(), and LOG_DEBUG.

Referenced by HandleChannelDisplayListQuery(), and OpcodeTable::Initialize().

◆ HandleChannelModerateOpcode()

void WorldSession::HandleChannelModerateOpcode ( WorldPacket recvPacket)
267{
268 std::string channelName;
269 recvPacket >> channelName;
270
271 LOG_DEBUG("chat.system", "CMSG_CHANNEL_MODERATE {} Channel: {}",
272 GetPlayerInfo(), channelName);
273
275 if (Channel* chn = cMgr->GetChannel(channelName, GetPlayer()))
276 chn->ToggleModeration(GetPlayer());
277}

References ChannelMgr::forTeam(), GetPlayer(), GetPlayerInfo(), GetTeamId(), and LOG_DEBUG.

Referenced by OpcodeTable::Initialize().

◆ HandleChannelModerator()

void WorldSession::HandleChannelModerator ( WorldPacket recvPacket)
135{
136 std::string channelName, targetName;
137 recvPacket >> channelName >> targetName;
138
139 LOG_DEBUG("chat.system", "CMSG_CHANNEL_MODERATOR {} Channel: {}, Target: {}",
140 GetPlayerInfo(), channelName, targetName);
141 if (!normalizePlayerName(targetName))
142 return;
143
145 if (Channel* channel = cMgr->GetChannel(channelName, GetPlayer()))
146 channel->SetModerator(GetPlayer(), targetName);
147}

References ChannelMgr::forTeam(), GetPlayer(), GetPlayerInfo(), GetTeamId(), LOG_DEBUG, and normalizePlayerName().

Referenced by OpcodeTable::Initialize().

◆ HandleChannelMute()

void WorldSession::HandleChannelMute ( WorldPacket recvPacket)
165{
166 std::string channelName, targetName;
167 recvPacket >> channelName >> targetName;
168
169 LOG_DEBUG("chat.system", "CMSG_CHANNEL_MUTE {} Channel: {}, Target: {}",
170 GetPlayerInfo(), channelName, targetName);
171 if (!normalizePlayerName(targetName))
172 return;
173
175 if (Channel* channel = cMgr->GetChannel(channelName, GetPlayer()))
176 channel->SetMute(GetPlayer(), targetName);
177}

References ChannelMgr::forTeam(), GetPlayer(), GetPlayerInfo(), GetTeamId(), LOG_DEBUG, and normalizePlayerName().

Referenced by OpcodeTable::Initialize().

◆ HandleChannelOwner()

void WorldSession::HandleChannelOwner ( WorldPacket recvPacket)
123{
124 std::string channelName;
125 recvPacket >> channelName;
126
127 LOG_DEBUG("chat.system", "CMSG_CHANNEL_OWNER {} Channel: {}",
128 GetPlayerInfo(), channelName);
130 if (Channel* channel = cMgr->GetChannel(channelName, GetPlayer()))
131 channel->SendWhoOwner(GetPlayer()->GetGUID());
132}

References ChannelMgr::forTeam(), GetPlayer(), GetPlayerInfo(), GetTeamId(), and LOG_DEBUG.

Referenced by OpcodeTable::Initialize().

◆ HandleChannelPassword()

void WorldSession::HandleChannelPassword ( WorldPacket recvPacket)
93{
94 std::string channelName, password;
95 recvPacket >> channelName >> password;
96
97 LOG_DEBUG("chat.system", "CMSG_CHANNEL_PASSWORD {} Channel: {}, Password: {}",
98 GetPlayerInfo(), channelName, password);
99 if (password.length() > MAX_CHANNEL_PASS_STR)
100 return;
101
103 if (Channel* channel = cMgr->GetChannel(channelName, GetPlayer()))
104 channel->Password(GetPlayer(), password);
105}
#define MAX_CHANNEL_PASS_STR
Definition: ChannelMgr.h:27

References ChannelMgr::forTeam(), GetPlayer(), GetPlayerInfo(), GetTeamId(), LOG_DEBUG, and MAX_CHANNEL_PASS_STR.

Referenced by OpcodeTable::Initialize().

◆ HandleChannelSetOwner()

void WorldSession::HandleChannelSetOwner ( WorldPacket recvPacket)
108{
109 std::string channelName, targetName;
110 recvPacket >> channelName >> targetName;
111
112 LOG_DEBUG("chat.system", "CMSG_CHANNEL_SET_OWNER {} Channel: {}, Target: {}",
113 GetPlayerInfo(), channelName, targetName);
114 if (!normalizePlayerName(targetName))
115 return;
116
118 if (Channel* channel = cMgr->GetChannel(channelName, GetPlayer()))
119 channel->SetOwner(GetPlayer(), targetName);
120}

References ChannelMgr::forTeam(), GetPlayer(), GetPlayerInfo(), GetTeamId(), LOG_DEBUG, and normalizePlayerName().

Referenced by OpcodeTable::Initialize().

◆ HandleChannelUnban()

void WorldSession::HandleChannelUnban ( WorldPacket recvPacket)
240{
241 std::string channelName, targetName;
242 recvPacket >> channelName >> targetName;
243
244 LOG_DEBUG("chat.system", "CMSG_CHANNEL_UNBAN {} Channel: {}, Target: {}",
245 GetPlayerInfo(), channelName, targetName);
246 if (!normalizePlayerName(targetName))
247 return;
248
250 if (Channel* channel = cMgr->GetChannel(channelName, GetPlayer()))
251 channel->UnBan(GetPlayer(), targetName);
252}

References ChannelMgr::forTeam(), GetPlayer(), GetPlayerInfo(), GetTeamId(), LOG_DEBUG, and normalizePlayerName().

Referenced by OpcodeTable::Initialize().

◆ HandleChannelUnmoderator()

void WorldSession::HandleChannelUnmoderator ( WorldPacket recvPacket)
150{
151 std::string channelName, targetName;
152 recvPacket >> channelName >> targetName;
153
154 LOG_DEBUG("chat.system", "CMSG_CHANNEL_UNMODERATOR {} Channel: {}, Target: {}",
155 GetPlayerInfo(), channelName, targetName);
156 if (!normalizePlayerName(targetName))
157 return;
158
160 if (Channel* channel = cMgr->GetChannel(channelName, GetPlayer()))
161 channel->UnsetModerator(GetPlayer(), targetName);
162}

References ChannelMgr::forTeam(), GetPlayer(), GetPlayerInfo(), GetTeamId(), LOG_DEBUG, and normalizePlayerName().

Referenced by OpcodeTable::Initialize().

◆ HandleChannelUnmute()

void WorldSession::HandleChannelUnmute ( WorldPacket recvPacket)
180{
181 std::string channelName, targetName;
182 recvPacket >> channelName >> targetName;
183
184 LOG_DEBUG("chat.system", "CMSG_CHANNEL_UNMUTE {} Channel: {}, Target: {}",
185 GetPlayerInfo(), channelName, targetName);
186 if (!normalizePlayerName(targetName))
187 return;
188
190 if (Channel* channel = cMgr->GetChannel(channelName, GetPlayer()))
191 channel->UnsetMute(GetPlayer(), targetName);
192}

References ChannelMgr::forTeam(), GetPlayer(), GetPlayerInfo(), GetTeamId(), LOG_DEBUG, and normalizePlayerName().

Referenced by OpcodeTable::Initialize().

◆ HandleChannelVoiceOnOpcode()

void WorldSession::HandleChannelVoiceOnOpcode ( WorldPacket recvData)
32{
33 LOG_DEBUG("network", "WORLD: CMSG_CHANNEL_VOICE_ON");
34 // Enable Voice button in channel context menu
35}

References LOG_DEBUG.

Referenced by OpcodeTable::Initialize().

◆ HandleCharacterAuraFrozen()

void WorldSession::HandleCharacterAuraFrozen ( PreparedQueryResult  result)
592{
593 if (!GetPlayer())
594 return;
595
596 ChatHandler handler = ChatHandler(this);
597
598 // Select
599 if (!result)
600 {
602 return;
603 }
604
605 // Header of the names
607
608 // Output of the results
609 do
610 {
611 Field* fields = result->Fetch();
612 std::string player = fields[0].Get<std::string>();
614 } while (result->NextRow());
615}
@ LANG_COMMAND_LIST_FREEZE
Definition: Language.h:1051
@ LANG_COMMAND_NO_FROZEN_PLAYERS
Definition: Language.h:1050
@ LANG_COMMAND_FROZEN_PLAYERS
Definition: Language.h:1052
std::enable_if_t< std::is_arithmetic_v< T >, T > Get() const
Definition: Field.h:112

References Field::Get(), GetPlayer(), LANG_COMMAND_FROZEN_PLAYERS, LANG_COMMAND_LIST_FREEZE, LANG_COMMAND_NO_FROZEN_PLAYERS, ChatHandler::PSendSysMessage(), and ChatHandler::SendSysMessage().

◆ HandleCharCreateOpcode()

void WorldSession::HandleCharCreateOpcode ( WorldPacket recvPacket)
Todo:
what to if account already has characters of both races?
Todo:
check if cinematic already shown? (already logged in?; cinematic field)
271{
272 std::shared_ptr<CharacterCreateInfo> createInfo = std::make_shared<CharacterCreateInfo>();
273
274 recvData >> createInfo->Name
275 >> createInfo->Race
276 >> createInfo->Class
277 >> createInfo->Gender
278 >> createInfo->Skin
279 >> createInfo->Face
280 >> createInfo->HairStyle
281 >> createInfo->HairColor
282 >> createInfo->FacialHair
283 >> createInfo->OutfitId;
284
286 {
287 if (uint32 mask = sWorld->getIntConfig(CONFIG_CHARACTER_CREATING_DISABLED))
288 {
289 if (mask & (1 << Player::TeamIdForRace(createInfo->Race)))
290 {
292 return;
293 }
294 }
295 }
296
297 ChrClassesEntry const* classEntry = sChrClassesStore.LookupEntry(createInfo->Class);
298 if (!classEntry)
299 {
301 LOG_ERROR("network.opcode", "Class ({}) not found in DBC while creating new char for account (ID: {}): wrong DBC files or cheater?", createInfo->Class, GetAccountId());
302 return;
303 }
304
305 ChrRacesEntry const* raceEntry = sChrRacesStore.LookupEntry(createInfo->Race);
306 if (!raceEntry)
307 {
309 LOG_ERROR("network.opcode", "Race ({}) not found in DBC while creating new char for account (ID: {}): wrong DBC files or cheater?", createInfo->Race, GetAccountId());
310 return;
311 }
312
313 // prevent character creating Expansion race without Expansion account
314 if (raceEntry->expansion > Expansion())
315 {
317 LOG_ERROR("network.opcode", "Expansion {} account:[{}] tried to Create character with expansion {} race ({})", Expansion(), GetAccountId(), raceEntry->expansion, createInfo->Race);
318 return;
319 }
320
321 // prevent character creating Expansion class without Expansion account
322 if (classEntry->expansion > Expansion())
323 {
325 LOG_ERROR("network.opcode", "Expansion {} account:[{}] tried to Create character with expansion {} class ({})", Expansion(), GetAccountId(), classEntry->expansion, createInfo->Class);
326 return;
327 }
328
330 {
331 uint32 raceMaskDisabled = sWorld->getIntConfig(CONFIG_CHARACTER_CREATING_DISABLED_RACEMASK);
332 if ((1 << (createInfo->Race - 1)) & raceMaskDisabled)
333 {
335 return;
336 }
337
338 uint32 classMaskDisabled = sWorld->getIntConfig(CONFIG_CHARACTER_CREATING_DISABLED_CLASSMASK);
339 if ((1 << (createInfo->Class - 1)) & classMaskDisabled)
340 {
342 return;
343 }
344 }
345
346 // prevent character creating with invalid name
347 if (!normalizePlayerName(createInfo->Name))
348 {
350 LOG_ERROR("network.opcode", "Account:[{}] but tried to Create character with empty [name] ", GetAccountId());
351 return;
352 }
353
354 // check name limitations
355 uint8 res = ObjectMgr::CheckPlayerName(createInfo->Name, true);
356 if (res != CHAR_NAME_SUCCESS)
357 {
359 return;
360 }
361
362 // speedup check for heroic class disabled case
363 uint32 heroic_free_slots = sWorld->getIntConfig(CONFIG_HEROIC_CHARACTERS_PER_REALM);
364 if (heroic_free_slots == 0 && AccountMgr::IsPlayerAccount(GetSecurity()) && createInfo->Class == CLASS_DEATH_KNIGHT)
365 {
367 return;
368 }
369
370 // speedup check for heroic class disabled case
371 uint32 req_level_for_heroic = sWorld->getIntConfig(CONFIG_CHARACTER_CREATING_MIN_LEVEL_FOR_HEROIC_CHARACTER);
372 if (AccountMgr::IsPlayerAccount(GetSecurity()) && createInfo->Class == CLASS_DEATH_KNIGHT && req_level_for_heroic > sWorld->getIntConfig(CONFIG_MAX_PLAYER_LEVEL))
373 {
375 return;
376 }
377
379 stmt->SetData(0, createInfo->Name);
380
382 .WithChainingPreparedCallback([this](QueryCallback& queryCallback, PreparedQueryResult result)
383 {
384 if (result)
385 {
386 SendCharCreate(CHAR_CREATE_NAME_IN_USE);
387 return;
388 }
389
391 stmt->SetData(0, GetAccountId());
392 queryCallback.SetNextQuery(LoginDatabase.AsyncQuery(stmt));
393 })
394 .WithChainingPreparedCallback([this](QueryCallback& queryCallback, PreparedQueryResult result)
395 {
396 uint64 acctCharCount = 0;
397 if (result)
398 {
399 Field* fields = result->Fetch();
400 acctCharCount = uint64(fields[0].Get<double>());
401 }
402
403 if (acctCharCount >= static_cast<uint64>(sWorld->getIntConfig(CONFIG_CHARACTERS_PER_ACCOUNT)))
404 {
406 return;
407 }
408
410 stmt->SetData(0, GetAccountId());
411 queryCallback.SetNextQuery(CharacterDatabase.AsyncQuery(stmt));
412 })
413 .WithChainingPreparedCallback([this, createInfo](QueryCallback& queryCallback, PreparedQueryResult result)
414 {
415 if (result)
416 {
417 Field* fields = result->Fetch();
418 createInfo->CharCount = uint8(fields[0].Get<uint64>()); // SQL's COUNT() returns uint64 but it will always be less than uint8.Max
419
420 if (createInfo->CharCount >= sWorld->getIntConfig(CONFIG_CHARACTERS_PER_REALM))
421 {
423 return;
424 }
425 }
426
427 bool allowTwoSideAccounts = !sWorld->IsPvPRealm() || sWorld->getBoolConfig(CONFIG_ALLOW_TWO_SIDE_ACCOUNTS) || !AccountMgr::IsPlayerAccount(GetSecurity());
428 uint32 skipCinematics = sWorld->getIntConfig(CONFIG_SKIP_CINEMATICS);
429
430 std::function<void(PreparedQueryResult)> finalizeCharacterCreation = [this, createInfo](PreparedQueryResult result)
431 {
432 if (!sScriptMgr->CanAccountCreateCharacter(GetAccountId(), createInfo->Race, createInfo->Class))
433 {
435 return;
436 }
437 bool haveSameRace = false;
439 bool hasHeroicReqLevel = (heroicReqLevel == 0);
440 bool allowTwoSideAccounts = !sWorld->IsPvPRealm() || sWorld->getBoolConfig(CONFIG_ALLOW_TWO_SIDE_ACCOUNTS) || !AccountMgr::IsPlayerAccount(GetSecurity());
441 uint32 skipCinematics = sWorld->getIntConfig(CONFIG_SKIP_CINEMATICS);
442 bool checkDeathKnightReqs = AccountMgr::IsPlayerAccount(GetSecurity()) && createInfo->Class == CLASS_DEATH_KNIGHT;
443
444 if (result)
445 {
446 TeamId teamId = Player::TeamIdForRace(createInfo->Race);
447 uint32 freeDeathKnightSlots = sWorld->getIntConfig(CONFIG_HEROIC_CHARACTERS_PER_REALM);
448
449 Field* field = result->Fetch();
450 uint8 accRace = field[1].Get<uint8>();
451
452 if (checkDeathKnightReqs)
453 {
454 uint8 accClass = field[2].Get<uint8>();
455 if (accClass == CLASS_DEATH_KNIGHT)
456 {
457 if (freeDeathKnightSlots > 0)
458 --freeDeathKnightSlots;
459
460 if (freeDeathKnightSlots == 0)
461 {
463 return;
464 }
465 }
466
467 if (!hasHeroicReqLevel)
468 {
469 uint8 accLevel = field[0].Get<uint8>();
470 if (accLevel >= heroicReqLevel)
471 hasHeroicReqLevel = true;
472 }
473 }
474
475 // need to check team only for first character
477 if (!allowTwoSideAccounts)
478 {
479 uint32 accTeam = 0;
480 if (accRace > 0)
481 accTeam = Player::TeamIdForRace(accRace);
482
483 if (accTeam != teamId)
484 {
486 return;
487 }
488 }
489
490 // search same race for cinematic or same class if need
492 while ((skipCinematics == 1 && !haveSameRace) || createInfo->Class == CLASS_DEATH_KNIGHT)
493 {
494 if (!result->NextRow())
495 break;
496
497 field = result->Fetch();
498 accRace = field[1].Get<uint8>();
499
500 if (!haveSameRace)
501 haveSameRace = createInfo->Race == accRace;
502
503 if (checkDeathKnightReqs)
504 {
505 uint8 acc_class = field[2].Get<uint8>();
506 if (acc_class == CLASS_DEATH_KNIGHT)
507 {
508 if (freeDeathKnightSlots > 0)
509 --freeDeathKnightSlots;
510
511 if (freeDeathKnightSlots == 0)
512 {
514 return;
515 }
516 }
517
518 if (!hasHeroicReqLevel)
519 {
520 uint8 acc_level = field[0].Get<uint8>();
521 if (acc_level >= heroicReqLevel)
522 hasHeroicReqLevel = true;
523 }
524 }
525 }
526 }
527
528 if (checkDeathKnightReqs && !hasHeroicReqLevel)
529 {
531 return;
532 }
533
534 // Check name uniqueness in the same step as saving to database
535 if (sCharacterCache->GetCharacterGuidByName(createInfo->Name))
536 {
538 return;
539 }
540
541 std::shared_ptr<Player> newChar(new Player(this), [](Player* ptr)
542 {
543 // Only when player is created correctly do clean
545 {
546 ptr->CleanupsBeforeDelete();
547 }
548 delete ptr;
549 });
550
551 newChar->GetMotionMaster()->Initialize();
552 if (!newChar->Create(sObjectMgr->GetGenerator<HighGuid::Player>().Generate(), createInfo.get()))
553 {
554 // Player not create (race/class/etc problem?)
556 return;
557 }
558
559 if ((haveSameRace && skipCinematics == 1) || skipCinematics == 2)
560 newChar->setCinematic(1); // not show intro
561
562 newChar->SetAtLoginFlag(AT_LOGIN_FIRST); // First login
563
564 CharacterDatabaseTransaction characterTransaction = CharacterDatabase.BeginTransaction();
565 LoginDatabaseTransaction trans = LoginDatabase.BeginTransaction();
566
567 // Player created, save it now
568 newChar->SaveToDB(characterTransaction, true, false);
569 createInfo->CharCount++;
570
572 stmt->SetData(0, createInfo->CharCount);
573 stmt->SetData(1, GetAccountId());
574 stmt->SetData(2, realm.Id.Realm);
575 trans->Append(stmt);
576
577 LoginDatabase.CommitTransaction(trans);
578
579 AddTransactionCallback(CharacterDatabase.AsyncCommitTransaction(characterTransaction)).AfterComplete([this, newChar = std::move(newChar)](bool success)
580 {
581 if (success)
582 {
583 LOG_INFO("entities.player.character", "Account: {} (IP: {}) Create Character: {} {}", GetAccountId(), GetRemoteAddress(), newChar->GetName(), newChar->GetGUID().ToString());
584 sScriptMgr->OnPlayerCreate(newChar.get());
585 sCharacterCache->AddCharacterCacheEntry(newChar->GetGUID(), GetAccountId(), newChar->GetName(), newChar->getGender(), newChar->getRace(), newChar->getClass(), newChar->GetLevel());
587 }
588 else
590 });
591 };
592
593 if (allowTwoSideAccounts && !skipCinematics && createInfo->Class != CLASS_DEATH_KNIGHT)
594 {
595 finalizeCharacterCreation(PreparedQueryResult(nullptr));
596 return;
597 }
598
600 stmt->SetData(0, GetAccountId());
601 stmt->SetData(1, (skipCinematics == 1 || createInfo->Class == CLASS_DEATH_KNIGHT) ? 10 : 1);
602 queryCallback.WithPreparedCallback(std::move(finalizeCharacterCreation)).SetNextQuery(CharacterDatabase.AsyncQuery(stmt));
603 }));
604}
DBCStorage< ChrRacesEntry > sChrRacesStore(ChrRacesEntryfmt)
DBCStorage< ChrClassesEntry > sChrClassesStore(ChrClassesEntryfmt)
@ CONFIG_CHARACTER_CREATING_DISABLED_CLASSMASK
Definition: IWorld.h:228
@ CONFIG_CHARACTER_CREATING_DISABLED
Definition: IWorld.h:226
@ CONFIG_CHARACTER_CREATING_DISABLED_RACEMASK
Definition: IWorld.h:227
@ CONFIG_CHARACTERS_PER_ACCOUNT
Definition: IWorld.h:229
@ CONFIG_HEROIC_CHARACTERS_PER_REALM
Definition: IWorld.h:232
@ CONFIG_CHARACTER_CREATING_MIN_LEVEL_FOR_HEROIC_CHARACTER
Definition: IWorld.h:233
@ CONFIG_SKIP_CINEMATICS
Definition: IWorld.h:234
@ CONFIG_CHARACTERS_PER_REALM
Definition: IWorld.h:230
@ CONFIG_ALLOW_TWO_SIDE_ACCOUNTS
Definition: IWorld.h:71
@ AT_LOGIN_FIRST
Definition: Player.h:605
SQLTransaction< LoginDatabaseConnection > LoginDatabaseTransaction
Definition: DatabaseEnvFwd.h:70
std::shared_ptr< PreparedResultSet > PreparedQueryResult
Definition: DatabaseEnvFwd.h:45
@ LOGIN_REP_REALM_CHARACTERS
Definition: LoginDatabase.h:63
@ LOGIN_SEL_SUM_REALM_CHARACTERS
Definition: LoginDatabase.h:64
@ CHAR_SEL_CHECK_NAME
Definition: CharacterDatabase.h:37
@ CHAR_SEL_SUM_CHARS
Definition: CharacterDatabase.h:39
@ CHAR_SEL_CHAR_CREATE_INFO
Definition: CharacterDatabase.h:40
ResponseCodes
Definition: SharedDefines.h:3320
@ CHAR_CREATE_EXPANSION
Definition: SharedDefines.h:3384
@ CHAR_NAME_NO_NAME
Definition: SharedDefines.h:3421
@ CHAR_CREATE_DISABLED
Definition: SharedDefines.h:3378
@ CHAR_CREATE_LEVEL_REQUIREMENT
Definition: SharedDefines.h:3386
@ CHAR_CREATE_FAILED
Definition: SharedDefines.h:3376
@ CHAR_CREATE_ERROR
Definition: SharedDefines.h:3375
@ CHAR_CREATE_NAME_IN_USE
Definition: SharedDefines.h:3377
@ CHAR_CREATE_SERVER_LIMIT
Definition: SharedDefines.h:3380
@ CHAR_CREATE_EXPANSION_CLASS
Definition: SharedDefines.h:3385
@ CHAR_CREATE_SUCCESS
Definition: SharedDefines.h:3374
@ CHAR_CREATE_PVP_TEAMS_VIOLATION
Definition: SharedDefines.h:3379
@ CHAR_CREATE_ACCOUNT_LIMIT
Definition: SharedDefines.h:3381
@ CHAR_CREATE_UNIQUE_CLASS_LIMIT
Definition: SharedDefines.h:3387
@ CHAR_NAME_SUCCESS
Definition: SharedDefines.h:3419
Definition: QueryCallback.h:29
void SetNextQuery(QueryCallback &&next)
Definition: QueryCallback.cpp:181
QueryCallback && WithPreparedCallback(std::function< void(PreparedQueryResult)> &&callback)
Definition: QueryCallback.cpp:162
void AfterComplete(std::function< void(bool)> callback) &
Definition: Transaction.h:116
bool HasAtLoginFlag(AtLoginFlags f) const
Definition: Player.h:2384
static uint8 CheckPlayerName(std::string_view name, bool create=false)
Definition: ObjectMgr.cpp:8374
uint8 Expansion() const
Definition: WorldSession.h:373
TransactionCallback & AddTransactionCallback(TransactionCallback &&callback)
Definition: WorldSession.cpp:1277
void SendCharCreate(ResponseCodes result)
Definition: CharacterHandler.cpp:2559
Definition: DBCStructure.h:652
uint32 expansion
Definition: DBCStructure.h:667
Definition: DBCStructure.h:678
uint32 expansion
Definition: DBCStructure.h:697

References _queryProcessor, AsyncCallbackProcessor< T >::AddCallback(), CHAR_CREATE_DISABLED, CHAR_CREATE_EXPANSION, CHAR_CREATE_EXPANSION_CLASS, CHAR_CREATE_FAILED, CHAR_CREATE_LEVEL_REQUIREMENT, CHAR_CREATE_UNIQUE_CLASS_LIMIT, CHAR_NAME_NO_NAME, CHAR_NAME_SUCCESS, CHAR_SEL_CHECK_NAME, CharacterDatabase, ObjectMgr::CheckPlayerName(), CLASS_DEATH_KNIGHT, CONFIG_CHARACTER_CREATING_DISABLED, CONFIG_CHARACTER_CREATING_DISABLED_CLASSMASK, CONFIG_CHARACTER_CREATING_DISABLED_RACEMASK, CONFIG_CHARACTER_CREATING_MIN_LEVEL_FOR_HEROIC_CHARACTER, CONFIG_HEROIC_CHARACTERS_PER_REALM, CONFIG_MAX_PLAYER_LEVEL, Expansion(), ChrClassesEntry::expansion, ChrRacesEntry::expansion, GetAccountId(), GetSecurity(), AccountMgr::IsPlayerAccount(), LOG_ERROR, LOGIN_SEL_SUM_REALM_CHARACTERS, LoginDatabase, normalizePlayerName(), sChrClassesStore, sChrRacesStore, SendCharCreate(), PreparedStatementBase::SetData(), QueryCallback::SetNextQuery(), sWorld, and Player::TeamIdForRace().

Referenced by OpcodeTable::Initialize().

◆ HandleCharCustomize()

void WorldSession::HandleCharCustomize ( WorldPacket recvData)
1614{
1615 std::shared_ptr<CharacterCustomizeInfo> customizeInfo = std::make_shared<CharacterCustomizeInfo>();
1616
1617 recvData >> customizeInfo->Guid;
1618
1619 if (!IsLegitCharacterForAccount(customizeInfo->Guid))
1620 {
1621 LOG_ERROR("entities.player.cheat", "Account {}, IP: {} tried to customise {}, but it does not belong to their account!",
1622 GetAccountId(), GetRemoteAddress(), customizeInfo->Guid.ToString());
1623 recvData.rfinish();
1624 KickPlayer("WorldSession::HandleCharCustomize Trying to customise character of another account");
1625 return;
1626 }
1627
1628 // pussywizard:
1629 if (ObjectAccessor::FindConnectedPlayer(customizeInfo->Guid) || sWorld->FindOfflineSessionForCharacterGUID(customizeInfo->Guid.GetCounter()))
1630 {
1631 recvData.rfinish();
1633 data << uint8(CHAR_CREATE_ERROR);
1634 SendPacket(&data);
1635 return;
1636 }
1637
1638 recvData >> customizeInfo->Name
1639 >> customizeInfo->Gender
1640 >> customizeInfo->Skin
1641 >> customizeInfo->HairColor
1642 >> customizeInfo->HairStyle
1643 >> customizeInfo->FacialHair
1644 >> customizeInfo->Face;
1645
1647 stmt->SetData(0, customizeInfo->Guid.GetCounter());
1648
1650 .WithPreparedCallback(std::bind(&WorldSession::HandleCharCustomizeCallback, this, customizeInfo, std::placeholders::_1)));
1651}
@ CHAR_SEL_CHAR_CUSTOMIZE_INFO
Definition: CharacterDatabase.h:344
@ SMSG_CHAR_CUSTOMIZE
Definition: Opcodes.h:1170
void HandleCharCustomizeCallback(std::shared_ptr< CharacterCustomizeInfo > customizeInfo, PreparedQueryResult result)
Definition: CharacterHandler.cpp:1653
bool IsLegitCharacterForAccount(ObjectGuid guid)
Definition: WorldSession.h:1134

References _queryProcessor, AsyncCallbackProcessor< T >::AddCallback(), CHAR_CREATE_ERROR, CHAR_SEL_CHAR_CUSTOMIZE_INFO, CharacterDatabase, ObjectAccessor::FindConnectedPlayer(), GetAccountId(), GetRemoteAddress(), HandleCharCustomizeCallback(), IsLegitCharacterForAccount(), KickPlayer(), LOG_ERROR, ByteBuffer::rfinish(), SendPacket(), PreparedStatementBase::SetData(), SMSG_CHAR_CUSTOMIZE, and sWorld.

Referenced by OpcodeTable::Initialize().

◆ HandleCharCustomizeCallback()

void WorldSession::HandleCharCustomizeCallback ( std::shared_ptr< CharacterCustomizeInfo customizeInfo,
PreparedQueryResult  result 
)

Customize

Name Change and update atLogin flags

1654{
1655 if (!result)
1656 {
1657 SendCharCustomize(CHAR_CREATE_ERROR, customizeInfo.get());
1658 return;
1659 }
1660
1661 // get the players old (at this moment current) race
1662 CharacterCacheEntry const* playerData = sCharacterCache->GetCharacterCacheByGuid(customizeInfo->Guid);
1663 if (!playerData)
1664 {
1665 SendCharCustomize(CHAR_CREATE_ERROR, customizeInfo.get());
1666 return;
1667 }
1668
1669 Field* fields = result->Fetch();
1670 std::string oldName = fields[0].Get<std::string>();
1671 //uint8 plrRace = fields[1].Get<uint8>();
1672 //uint8 plrClass = fields[2].Get<uint8>();
1673 //uint8 plrGender = fields[3].Get<uint8>();
1674 uint32 atLoginFlags = fields[4].Get<uint16>();
1675
1676 if (!(atLoginFlags & AT_LOGIN_CUSTOMIZE))
1677 {
1678 SendCharCustomize(CHAR_CREATE_ERROR, customizeInfo.get());
1679 return;
1680 }
1681
1682 atLoginFlags &= ~AT_LOGIN_CUSTOMIZE;
1683
1684 // prevent character rename to invalid name
1685 if (!normalizePlayerName(customizeInfo->Name))
1686 {
1687 SendCharCustomize(CHAR_NAME_NO_NAME, customizeInfo.get());
1688 return;
1689 }
1690
1691 ResponseCodes res = static_cast<ResponseCodes>(ObjectMgr::CheckPlayerName(customizeInfo->Name, true));
1692 if (res != CHAR_NAME_SUCCESS)
1693 {
1694 SendCharCustomize(res, customizeInfo.get());
1695 return;
1696 }
1697
1698 // character with this name already exist
1699 if (ObjectGuid newguid = sCharacterCache->GetCharacterGuidByName(customizeInfo->Name))
1700 {
1701 if (newguid != customizeInfo->Guid)
1702 {
1703 SendCharCustomize(CHAR_CREATE_NAME_IN_USE, customizeInfo.get());
1704 return;
1705 }
1706 }
1707
1708 CharacterDatabasePreparedStatement* stmt = nullptr;
1709 CharacterDatabaseTransaction trans = CharacterDatabase.BeginTransaction();
1710
1711 ObjectGuid::LowType lowGuid = customizeInfo->Guid.GetCounter();
1712
1714 Player::Customize(customizeInfo.get(), trans);
1715
1717 {
1718 stmt = CharacterDatabase.GetPreparedStatement(CHAR_UPD_CHAR_NAME_AT_LOGIN);
1719 stmt->SetData(0, customizeInfo->Name);
1720 stmt->SetData(1, atLoginFlags);
1721 stmt->SetData(2, lowGuid);
1722
1723 trans->Append(stmt);
1724
1725 if (sWorld->getBoolConfig(CONFIG_DECLINED_NAMES_USED))
1726 {
1727 stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_DECLINED_NAME);
1728 stmt->SetData(0, lowGuid);
1729
1730 trans->Append(stmt);
1731 }
1732 }
1733
1734 CharacterDatabase.CommitTransaction(trans);
1735
1736 sCharacterCache->UpdateCharacterData(customizeInfo->Guid, customizeInfo->Name, customizeInfo->Gender);
1737
1738 SendCharCustomize(RESPONSE_SUCCESS, customizeInfo.get());
1739
1740 LOG_INFO("entities.player.character", "Account: {} (IP: {}), Character[{}] ({}) Customized to: {}",
1741 GetAccountId(), GetRemoteAddress(), oldName, customizeInfo->Guid.ToString(), customizeInfo->Name);
1742}
@ CONFIG_DECLINED_NAMES_USED
Definition: IWorld.h:108
@ AT_LOGIN_CUSTOMIZE
Definition: Player.h:603
@ CHAR_DEL_DECLINED_NAME
Definition: CharacterDatabase.h:138
@ CHAR_UPD_CHAR_NAME_AT_LOGIN
Definition: CharacterDatabase.h:303
@ RESPONSE_SUCCESS
Definition: SharedDefines.h:3321
uint32 LowType
Definition: ObjectGuid.h:122
static void Customize(CharacterCustomizeInfo const *customizeInfo, CharacterDatabaseTransaction trans)
Definition: PlayerMisc.cpp:114
void SendCharCustomize(ResponseCodes result, CharacterCustomizeInfo const *customizeInfo)
Definition: CharacterHandler.cpp:2604

References AT_LOGIN_CUSTOMIZE, CHAR_CREATE_ERROR, CHAR_CREATE_NAME_IN_USE, CHAR_DEL_DECLINED_NAME, CHAR_NAME_NO_NAME, CHAR_NAME_SUCCESS, CHAR_UPD_CHAR_NAME_AT_LOGIN, CharacterDatabase, ObjectMgr::CheckPlayerName(), CONFIG_DECLINED_NAMES_USED, Player::Customize(), Field::Get(), GetAccountId(), GetRemoteAddress(), LOG_INFO, normalizePlayerName(), RESPONSE_SUCCESS, sCharacterCache, SendCharCustomize(), PreparedStatementBase::SetData(), and sWorld.

Referenced by HandleCharCustomize().

◆ HandleCharDeleteOpcode()

void WorldSession::HandleCharDeleteOpcode ( WorldPacket recvPacket)
607{
608 ObjectGuid guid;
609 recvData >> guid;
610
611 // Initiating
612 uint32 initAccountId = GetAccountId();
613
614 // can't delete loaded character
615 if (ObjectAccessor::FindConnectedPlayer(guid) || sWorld->FindOfflineSessionForCharacterGUID(guid.GetCounter()))
616 {
617 sScriptMgr->OnPlayerFailedDelete(guid, initAccountId);
618 return;
619 }
620
621 uint32 accountId = 0;
622 uint8 level = 0;
623 std::string name;
624
625 // is guild leader
626 if (sGuildMgr->GetGuildByLeader(guid))
627 {
628 sScriptMgr->OnPlayerFailedDelete(guid, initAccountId);
630 return;
631 }
632
633 // is arena team captain
634 if (sArenaTeamMgr->GetArenaTeamByCaptain(guid))
635 {
636 sScriptMgr->OnPlayerFailedDelete(guid, initAccountId);
638 return;
639 }
640
641 if (CharacterCacheEntry const* playerData = sCharacterCache->GetCharacterCacheByGuid(guid))
642 {
643 accountId = playerData->AccountId;
644 name = playerData->Name;
645 level = playerData->Level;
646 }
647
648 // prevent deleting other players' characters using cheating tools
649 if (accountId != initAccountId)
650 {
651 sScriptMgr->OnPlayerFailedDelete(guid, initAccountId);
652 return;
653 }
654
655 LOG_INFO("entities.player.character", "Account: {}, IP: {} deleted character: {}, {}, Level: {}", accountId, GetRemoteAddress(), name, guid.ToString(), level);
656
657 // To prevent hook failure, place hook before removing reference from DB
658 sScriptMgr->OnPlayerDelete(guid, initAccountId); // To prevent race conditioning, but as it also makes sense, we hand the accountId over for successful delete.
659 sCalendarMgr->RemoveAllPlayerEventsAndInvites(guid);
660 Player::DeleteFromDB(guid.GetCounter(), GetAccountId(), true, false);
661
662 sWorld->UpdateRealmCharCount(GetAccountId());
663
665}
@ CHAR_DELETE_SUCCESS
Definition: SharedDefines.h:3401
@ CHAR_DELETE_FAILED_GUILD_LEADER
Definition: SharedDefines.h:3404
@ CHAR_DELETE_FAILED_ARENA_CAPTAIN
Definition: SharedDefines.h:3405
static void DeleteFromDB(ObjectGuid::LowType lowGuid, uint32 accountId, bool updateRealmChars, bool deleteFinally)
Definition: Player.cpp:3955
void SendCharDelete(ResponseCodes result)
Definition: CharacterHandler.cpp:2566

References CHAR_DELETE_FAILED_ARENA_CAPTAIN, CHAR_DELETE_FAILED_GUILD_LEADER, CHAR_DELETE_SUCCESS, Player::DeleteFromDB(), ObjectAccessor::FindConnectedPlayer(), GetAccountId(), ObjectGuid::GetCounter(), GetRemoteAddress(), LOG_INFO, sArenaTeamMgr, sCalendarMgr, sCharacterCache, SendCharDelete(), sGuildMgr, sScriptMgr, sWorld, and ObjectGuid::ToString().

Referenced by OpcodeTable::Initialize().

◆ HandleCharEnum()

void WorldSession::HandleCharEnum ( PreparedQueryResult  result)
226{
227 WorldPacket data(SMSG_CHAR_ENUM, 100); // we guess size
228
229 uint8 num = 0;
230
231 data << num;
232
233 _legitCharacters.clear();
234 if (result)
235 {
236 do
237 {
238 ObjectGuid guid = ObjectGuid::Create<HighGuid::Player>((*result)[0].Get<uint32>());
239 LOG_DEBUG("network.opcode", "Loading char {} from account {}.", guid.ToString(), GetAccountId());
240 if (Player::BuildEnumData(result, &data))
241 {
242 _legitCharacters.insert(guid);
243 ++num;
244 }
245 } while (result->NextRow());
246 }
247
248 data.put<uint8>(0, num);
249
250 SendPacket(&data);
251}
@ SMSG_CHAR_ENUM
Definition: Opcodes.h:89
static bool BuildEnumData(PreparedQueryResult result, WorldPacket *data)
Definition: Player.cpp:1086
GuidSet _legitCharacters
Definition: WorldSession.h:1141

References _legitCharacters, Player::BuildEnumData(), GetAccountId(), LOG_DEBUG, ByteBuffer::put(), SendPacket(), SMSG_CHAR_ENUM, and ObjectGuid::ToString().

Referenced by HandleCharEnumOpcode().

◆ HandleCharEnumOpcode()

void WorldSession::HandleCharEnumOpcode ( WorldPacket recvPacket)

get all the data necessary for loading all characters (along with their pets) on the account

254{
256
258
259 if (sWorld->getBoolConfig(CONFIG_DECLINED_NAMES_USED))
260 stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_ENUM_DECLINED_NAME);
261 else
262 stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_ENUM);
263
265 stmt->SetData(1, GetAccountId());
266
267 _queryProcessor.AddCallback(CharacterDatabase.AsyncQuery(stmt).WithPreparedCallback(std::bind(&WorldSession::HandleCharEnum, this, std::placeholders::_1)));
268}
@ PET_SAVE_AS_CURRENT
Definition: PetDefines.h:42
@ CHAR_SEL_ENUM
Definition: CharacterDatabase.h:48
@ CHAR_SEL_ENUM_DECLINED_NAME
Definition: CharacterDatabase.h:49
void HandleCharEnum(PreparedQueryResult result)
Definition: CharacterHandler.cpp:225

References _queryProcessor, AsyncCallbackProcessor< T >::AddCallback(), CHAR_SEL_ENUM, CHAR_SEL_ENUM_DECLINED_NAME, CharacterDatabase, CONFIG_DECLINED_NAMES_USED, GetAccountId(), HandleCharEnum(), PET_SAVE_AS_CURRENT, PreparedStatementBase::SetData(), and sWorld.

Referenced by OpcodeTable::Initialize().

◆ HandleCharFactionOrRaceChange()

void WorldSession::HandleCharFactionOrRaceChange ( WorldPacket recvData)
1907{
1908 std::shared_ptr<CharacterFactionChangeInfo> factionChangeInfo = std::make_shared<CharacterFactionChangeInfo>();
1909
1910 recvData >> factionChangeInfo->Guid;
1911
1912 if (!IsLegitCharacterForAccount(factionChangeInfo->Guid))
1913 {
1914 LOG_ERROR("entities.player.cheat", "Account {}, IP: {} tried to factionchange character {}, but it does not belong to their account!",
1915 GetAccountId(), GetRemoteAddress(), factionChangeInfo->Guid.ToString());
1916 recvData.rfinish();
1917 KickPlayer("WorldSession::HandleCharFactionOrRaceChange Trying to change faction of character of another account");
1918 return;
1919 }
1920
1921 recvData >> factionChangeInfo->Name
1922 >> factionChangeInfo->Gender
1923 >> factionChangeInfo->Skin
1924 >> factionChangeInfo->HairColor
1925 >> factionChangeInfo->HairStyle
1926 >> factionChangeInfo->FacialHair
1927 >> factionChangeInfo->Face
1928 >> factionChangeInfo->Race;
1929
1930 // pussywizard:
1931 if (ObjectAccessor::FindConnectedPlayer(factionChangeInfo->Guid) || sWorld->FindOfflineSessionForCharacterGUID(factionChangeInfo->Guid.GetCounter()))
1932 {
1933 SendCharFactionChange(CHAR_CREATE_ERROR, factionChangeInfo.get());
1934 return;
1935 }
1936
1937 factionChangeInfo->FactionChange = (recvData.GetOpcode() == CMSG_CHAR_FACTION_CHANGE);
1938
1940 stmt->SetData(0, factionChangeInfo->Guid.GetCounter());
1941
1943 .WithPreparedCallback(std::bind(&WorldSession::HandleCharFactionOrRaceChangeCallback, this, factionChangeInfo, std::placeholders::_1)));
1944}
@ CHAR_SEL_CHAR_RACE_OR_FACTION_CHANGE_INFOS
Definition: CharacterDatabase.h:345
@ CMSG_CHAR_FACTION_CHANGE
Definition: Opcodes.h:1271
void HandleCharFactionOrRaceChangeCallback(std::shared_ptr< CharacterFactionChangeInfo > factionChangeInfo, PreparedQueryResult result)
Definition: CharacterHandler.cpp:1946
void SendCharFactionChange(ResponseCodes result, CharacterFactionChangeInfo const *factionChangeInfo)
Definition: CharacterHandler.cpp:2585

References _queryProcessor, AsyncCallbackProcessor< T >::AddCallback(), CHAR_CREATE_ERROR, CHAR_SEL_CHAR_RACE_OR_FACTION_CHANGE_INFOS, CharacterDatabase, CMSG_CHAR_FACTION_CHANGE, ObjectAccessor::FindConnectedPlayer(), GetAccountId(), WorldPacket::GetOpcode(), GetRemoteAddress(), HandleCharFactionOrRaceChangeCallback(), IsLegitCharacterForAccount(), KickPlayer(), LOG_ERROR, ByteBuffer::rfinish(), SendCharFactionChange(), PreparedStatementBase::SetData(), and sWorld.

Referenced by OpcodeTable::Initialize().

◆ HandleCharFactionOrRaceChangeCallback()

void WorldSession::HandleCharFactionOrRaceChangeCallback ( std::shared_ptr< CharacterFactionChangeInfo factionChangeInfo,
PreparedQueryResult  result 
)
1947{
1948 if (!result)
1949 {
1950 SendCharFactionChange(CHAR_CREATE_ERROR, factionChangeInfo.get());
1951 return;
1952 }
1953
1954 ObjectGuid::LowType lowGuid = factionChangeInfo->Guid.GetCounter();
1955
1956 // get the players old (at this moment current) race
1957 CharacterCacheEntry const* playerData = sCharacterCache->GetCharacterCacheByGuid(factionChangeInfo->Guid);
1958 if (!playerData)
1959 {
1960 SendCharFactionChange(CHAR_CREATE_ERROR, factionChangeInfo.get());
1961 return;
1962 }
1963
1964 uint8 oldRace = playerData->Race;
1965 uint8 playerClass = playerData->Class;
1966 uint8 level = playerData->Level;
1967
1968 if (!sObjectMgr->GetPlayerInfo(factionChangeInfo->Race, playerClass))
1969 {
1970 SendCharFactionChange(CHAR_CREATE_ERROR, factionChangeInfo.get());
1971 return;
1972 }
1973
1974 Field* fields = result->Fetch();
1975 uint32 atLoginFlags = fields[0].Get<uint16>();
1976 std::string knownTitlesStr = fields[1].Get<std::string>();
1977 uint32 money = fields[2].Get<uint32>();
1978
1979 uint32 usedLoginFlag = (factionChangeInfo->FactionChange ? AT_LOGIN_CHANGE_FACTION : AT_LOGIN_CHANGE_RACE);
1980 if (!(atLoginFlags & usedLoginFlag))
1981 {
1982 SendCharFactionChange(CHAR_CREATE_ERROR, factionChangeInfo.get());
1983 return;
1984 }
1985
1986 // xinef: add some safety checks
1987 if (factionChangeInfo->FactionChange)
1988 {
1989 // if player is in a guild
1990 if (playerData->GuildId && !sWorld->getBoolConfig(CONFIG_ALLOW_TWO_SIDE_INTERACTION_GUILD))
1991 {
1992 SendCharFactionChange(CHAR_CREATE_CHARACTER_IN_GUILD, factionChangeInfo.get());
1993 return;
1994 }
1995
1996 // is arena team captain
1997 if (sArenaTeamMgr->GetArenaTeamByCaptain(factionChangeInfo->Guid))
1998 {
2000 return;
2001 }
2002
2003 // check mailbox
2004 if (playerData->MailCount)
2005 {
2007 return;
2008 }
2009
2010 // check auctions, current packet is processed single-threaded way, so not a problem
2011 bool has_auctions = false;
2012
2013 for (uint8 i = 0; i < 2; ++i) // check both neutral and faction-specific AH
2014 {
2015 AuctionHouseObject* auctionHouse = sAuctionMgr->GetAuctionsMap(i == 0 ? 0 : (((1 << (playerData->Race - 1)) & RACEMASK_ALLIANCE) ? 12 : 29));
2016
2017 for (auto const& [auID, Aentry] : auctionHouse->GetAuctions())
2018 {
2019 if (Aentry && (Aentry->owner == factionChangeInfo->Guid || Aentry->bidder == factionChangeInfo->Guid))
2020 {
2021 has_auctions = true;
2022 break;
2023 }
2024 }
2025
2026 if (has_auctions)
2027 break;
2028 }
2029
2030 if (has_auctions)
2031 {
2032 SendCharFactionChange(CHAR_CREATE_ERROR, factionChangeInfo.get());
2033 return;
2034 }
2035 }
2036
2037 TeamId newTeam = Player::TeamIdForRace(factionChangeInfo->Race);
2038 if (factionChangeInfo->FactionChange == (Player::TeamIdForRace(oldRace) == newTeam))
2039 {
2040 SendCharFactionChange(factionChangeInfo->FactionChange ? CHAR_CREATE_CHARACTER_SWAP_FACTION : CHAR_CREATE_CHARACTER_RACE_ONLY, factionChangeInfo.get());
2041 return;
2042 }
2043
2044 uint32 maxMoney = sWorld->getIntConfig(CONFIG_CHANGE_FACTION_MAX_MONEY);
2045 if (maxMoney && money > maxMoney)
2046 {
2048 return;
2049 }
2050
2051 // pussywizard: check titles here to prevent return while building queries
2052 const uint32 ktcount = KNOWN_TITLES_SIZE * 2;
2053 std::vector<std::string_view> tokens = Acore::Tokenize(knownTitlesStr, ' ', false);
2054
2055 if (factionChangeInfo->FactionChange && tokens.size() != ktcount)
2056 {
2057 SendCharFactionChange(CHAR_CREATE_ERROR, factionChangeInfo.get());
2058 return;
2059 }
2060
2062 {
2063 uint32 raceMaskDisabled = sWorld->getIntConfig(CONFIG_CHARACTER_CREATING_DISABLED_RACEMASK);
2064 if ((1 << (factionChangeInfo->Race - 1)) & raceMaskDisabled)
2065 {
2066 SendCharFactionChange(CHAR_CREATE_ERROR, factionChangeInfo.get());
2067 return;
2068 }
2069 }
2070
2071 // prevent character rename to invalid name
2072 if (!normalizePlayerName(factionChangeInfo->Name))
2073 {
2074 SendCharFactionChange(CHAR_NAME_NO_NAME, factionChangeInfo.get());
2075 return;
2076 }
2077
2078 ResponseCodes res = static_cast<ResponseCodes>(ObjectMgr::CheckPlayerName(factionChangeInfo->Name, true));
2079 if (res != CHAR_NAME_SUCCESS)
2080 {
2081 SendCharFactionChange(res, factionChangeInfo.get());
2082 return;
2083 }
2084
2085 // character with this name already exist
2086 if (ObjectGuid newguid = sCharacterCache->GetCharacterGuidByName(factionChangeInfo->Name))
2087 {
2088 if (newguid != factionChangeInfo->Guid)
2089 {
2090 SendCharFactionChange(CHAR_CREATE_NAME_IN_USE, factionChangeInfo.get());
2091 return;
2092 }
2093 }
2094
2095 CharacterDatabasePreparedStatement* stmt = nullptr;
2096 CharacterDatabaseTransaction trans = CharacterDatabase.BeginTransaction();
2097
2098 // resurrect the character in case he's dead
2099 Player::OfflineResurrect(factionChangeInfo->Guid, trans);
2100
2101 // Name Change and update atLogin flags
2102 {
2103 CharacterDatabase.EscapeString(factionChangeInfo->Name);
2104
2105 stmt = CharacterDatabase.GetPreparedStatement(CHAR_UPD_CHAR_NAME_AT_LOGIN);
2106 stmt->SetData(0, factionChangeInfo->Name);
2107 stmt->SetData(1, uint16((atLoginFlags | AT_LOGIN_RESURRECT) & ~usedLoginFlag));
2108 stmt->SetData(2, lowGuid);
2109 trans->Append(stmt);
2110
2111 stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_CHAR_DECLINED_NAME);
2112 stmt->SetData(0, lowGuid);
2113 trans->Append(stmt);
2114 }
2115
2116 // Customize
2117 Player::Customize(factionChangeInfo.get(), trans);
2118
2119 // Race Change
2120 {
2121 stmt = CharacterDatabase.GetPreparedStatement(CHAR_UPD_CHAR_RACE);
2122 stmt->SetData(0, factionChangeInfo->Race);
2123 stmt->SetData(1, lowGuid);
2124 trans->Append(stmt);
2125 }
2126
2127 LOG_INFO("entities.player.character", "Account: {} (IP: {}), Character [{}] (guid: {}) Changed Race/Faction to: {}",
2128 GetAccountId(), GetRemoteAddress(), playerData->Name, lowGuid, factionChangeInfo->Name);
2129
2130 // xinef: update global data
2131 sCharacterCache->UpdateCharacterData(factionChangeInfo->Guid, factionChangeInfo->Name, factionChangeInfo->Gender, factionChangeInfo->Race);
2132
2133 if (oldRace != factionChangeInfo->Race)
2134 {
2135 // Switch Languages
2136 // delete all languages first
2137 stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_CHAR_SKILL_LANGUAGES);
2138 stmt->SetData(0, lowGuid);
2139 trans->Append(stmt);
2140
2141 // Now add them back
2142 stmt = CharacterDatabase.GetPreparedStatement(CHAR_INS_CHAR_SKILL_LANGUAGE);
2143 stmt->SetData(0, lowGuid);
2144
2145 // Faction specific languages
2146 if (newTeam == TEAM_HORDE)
2147 stmt->SetData(1, 109);
2148 else
2149 stmt->SetData(1, 98);
2150
2151 trans->Append(stmt);
2152
2153 // Race specific languages
2154 if (factionChangeInfo->Race != RACE_ORC && factionChangeInfo->Race != RACE_HUMAN)
2155 {
2156 stmt = CharacterDatabase.GetPreparedStatement(CHAR_INS_CHAR_SKILL_LANGUAGE);
2157 stmt->SetData(0, lowGuid);
2158
2159 switch (factionChangeInfo->Race)
2160 {
2161 case RACE_DWARF:
2162 stmt->SetData(1, 111);
2163 break;
2164 case RACE_DRAENEI:
2165 stmt->SetData(1, 759);
2166 break;
2167 case RACE_GNOME:
2168 stmt->SetData(1, 313);
2169 break;
2170 case RACE_NIGHTELF:
2171 stmt->SetData(1, 113);
2172 break;
2173 case RACE_UNDEAD_PLAYER:
2174 stmt->SetData(1, 673);
2175 break;
2176 case RACE_TAUREN:
2177 stmt->SetData(1, 115);
2178 break;
2179 case RACE_TROLL:
2180 stmt->SetData(1, 315);
2181 break;
2182 case RACE_BLOODELF:
2183 stmt->SetData(1, 137);
2184 break;
2185 }
2186
2187 trans->Append(stmt);
2188 }
2189
2190 if (factionChangeInfo->FactionChange)
2191 {
2192 {
2193 // Delete all Flypaths
2194 stmt = CharacterDatabase.GetPreparedStatement(CHAR_UPD_CHAR_TAXI_PATH);
2195 stmt->SetData(0, lowGuid);
2196 trans->Append(stmt);
2197
2198 // Update Taxi path
2199 TaxiMask newTaxiMask;
2200 newTaxiMask.fill(0);
2201
2202 TaxiMask const& factionMask = newTeam == TEAM_HORDE ? sHordeTaxiNodesMask : sAllianceTaxiNodesMask;
2203 for (auto const& itr : sTaxiPathSetBySource)
2204 {
2205 auto FillTaxiMask = [&](uint8 field, uint32 mask)
2206 {
2207 if (playerClass == CLASS_DEATH_KNIGHT)
2208 {
2209 newTaxiMask[field] |= uint32(mask | (sDeathKnightTaxiNodesMask[field] & mask));
2210 }
2211 else
2212 {
2213 newTaxiMask[field] |= mask;
2214 }
2215 };
2216
2217 uint32 nodeId = itr.first;
2218 uint8 field = (uint8)((nodeId - 1) / 32);
2219 uint32 submask = 1 << ((nodeId - 1) % 32);
2220
2221 if ((factionMask[field] & submask) == 0)
2222 {
2223 FillTaxiMask(field, 0);
2224 continue;
2225 }
2226
2227 TaxiPathSetForSource const& taxiPaths = itr.second;
2228 if (taxiPaths.empty())
2229 {
2230 FillTaxiMask(field, 0);
2231 continue;
2232 }
2233
2234 TaxiPathEntry const* taxiPath = taxiPaths.begin()->second;
2235 if (!taxiPath)
2236 {
2237 FillTaxiMask(field, 0);
2238 continue;
2239 }
2240
2241 TaxiPathNodeList const& taxiNodePaths = sTaxiPathNodesByPath[taxiPath->ID];
2242 if (taxiNodePaths.empty())
2243 {
2244 FillTaxiMask(field, 0);
2245 continue;
2246 }
2247
2248 TaxiPathNodeEntry const* pathNode = taxiNodePaths.front();
2249 if (!pathNode)
2250 {
2251 FillTaxiMask(field, 0);
2252 continue;
2253 }
2254
2255 AreaTableEntry const* zone = sAreaTableStore.LookupEntry(sMapMgr->GetZoneId(PHASEMASK_NORMAL, pathNode->mapid, pathNode->x, pathNode->y, pathNode->z));
2256 if (!zone)
2257 {
2258 FillTaxiMask(field, 0);
2259 continue;
2260 }
2261
2263 if (!lfgDungeon)
2264 {
2265 FillTaxiMask(field, 0);
2266 continue;
2267 }
2268
2269 // Get level from LFGDungeonEntry because the one from AreaTableEntry is not valid
2270 // If area level is too big, do not add new taxi
2271 if (lfgDungeon->MinLevel > level)
2272 {
2273 FillTaxiMask(field, 0);
2274 continue;
2275 }
2276
2277 FillTaxiMask(field, submask);
2278 }
2279
2280 std::ostringstream taximaskstream;
2281 for (uint8 i = 0; i < TaxiMaskSize; ++i)
2282 taximaskstream << uint32(newTaxiMask[i]) << ' ';
2283
2284 stmt = CharacterDatabase.GetPreparedStatement(CHAR_UPD_CHAR_TAXIMASK);
2285 stmt->SetData(0, taximaskstream.str());
2286 stmt->SetData(1, lowGuid);
2287 trans->Append(stmt);
2288 }
2289
2290 // Reset guild
2292 {
2293 if (uint32 guildId = playerData->GuildId)
2294 if (Guild* guild = sGuildMgr->GetGuildById(guildId))
2295 guild->DeleteMember(factionChangeInfo->Guid, false, false, true);
2296 }
2297
2298 if (!sWorld->getBoolConfig(CONFIG_ALLOW_TWO_SIDE_ADD_FRIEND))
2299 {
2300 // Delete Friend List
2301 stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_CHAR_SOCIAL_BY_GUID);
2302 stmt->SetData(0, lowGuid);
2303 trans->Append(stmt);
2304
2305 stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_CHAR_SOCIAL_BY_FRIEND);
2306 stmt->SetData(0, lowGuid);
2307 trans->Append(stmt);
2308 }
2309
2310 // Leave Arena Teams
2311 Player::LeaveAllArenaTeams(factionChangeInfo->Guid);
2312
2313 // Reset homebind and position
2314 stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_PLAYER_HOMEBIND);
2315 stmt->SetData(0, lowGuid);
2316 trans->Append(stmt);
2317
2318 stmt = CharacterDatabase.GetPreparedStatement(CHAR_INS_PLAYER_HOMEBIND);
2319 stmt->SetData(0, lowGuid);
2320
2321 WorldLocation loc;
2322 uint16 zoneId = 0;
2323
2324 if (newTeam == TEAM_ALLIANCE)
2325 {
2326 loc.WorldRelocate(0, -8867.68f, 673.373f, 97.9034f, 0.0f);
2327 zoneId = 1519;
2328 }
2329 else
2330 {
2331 loc.WorldRelocate(1, 1633.33f, -4439.11f, 15.7588f, 0.0f);
2332 zoneId = 1637;
2333 }
2334
2335 stmt->SetData(1, loc.GetMapId());
2336 stmt->SetData(2, zoneId);
2337 stmt->SetData(3, loc.GetPositionX());
2338 stmt->SetData(4, loc.GetPositionY());
2339 stmt->SetData(5, loc.GetPositionZ());
2340 trans->Append(stmt);
2341
2342 Player::SavePositionInDB(loc, zoneId, factionChangeInfo->Guid, trans);
2343
2344 // Achievement conversion
2345 for (auto const& [achiev_alliance, achiev_horde] : sObjectMgr->FactionChangeAchievements)
2346 {
2348 stmt->SetData(0, uint16(newTeam == TEAM_ALLIANCE ? achiev_alliance : achiev_horde));
2349 stmt->SetData(1, lowGuid);
2350 trans->Append(stmt);
2351
2352 stmt = CharacterDatabase.GetPreparedStatement(CHAR_UPD_CHAR_ACHIEVEMENT);
2353 stmt->SetData(0, uint16(newTeam == TEAM_ALLIANCE ? achiev_alliance : achiev_horde));
2354 stmt->SetData(1, uint16(newTeam == TEAM_ALLIANCE ? achiev_horde : achiev_alliance));
2355 stmt->SetData(2, lowGuid);
2356 trans->Append(stmt);
2357 }
2358
2359 // Item conversion
2360 for (auto const& [item_alliance, item_horde] : sObjectMgr->FactionChangeItems)
2361 {
2362 uint32 new_entry = (newTeam == TEAM_ALLIANCE ? item_alliance : item_horde);
2363 uint32 old_entry = (newTeam == TEAM_ALLIANCE ? item_horde : item_alliance);
2364
2365 if (old_entry == 45978 /*Solid Gold Coin*/ || old_entry == 2589 /*Linen Cloth*/ || old_entry == 5976 /*Guild Tabard*/)
2366 continue;
2367
2368 stmt = CharacterDatabase.GetPreparedStatement(CHAR_UPD_CHAR_INVENTORY_FACTION_CHANGE);
2369 stmt->SetData(0, new_entry);
2370 stmt->SetData(1, old_entry);
2371 stmt->SetData(2, lowGuid);
2372 trans->Append(stmt);
2373 }
2374
2375 // Delete all current quests
2376 stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_CHAR_QUESTSTATUS);
2377 stmt->SetData(0, lowGuid);
2378 trans->Append(stmt);
2379
2380 // Quest conversion
2381 for (auto const& [quest_alliance, quest_horde] : sObjectMgr->FactionChangeQuests)
2382 {
2384 stmt->SetData(0, lowGuid);
2385 stmt->SetData(1, (newTeam == TEAM_ALLIANCE ? quest_alliance : quest_horde));
2386 trans->Append(stmt);
2387
2389 stmt->SetData(0, (newTeam == TEAM_ALLIANCE ? quest_alliance : quest_horde));
2390 stmt->SetData(1, (newTeam == TEAM_ALLIANCE ? quest_horde : quest_alliance));
2391 stmt->SetData(2, lowGuid);
2392 trans->Append(stmt);
2393 }
2394
2395 // Mark all rewarded quests as "active" (will count for completed quests achievements)
2397 stmt->SetData(0, lowGuid);
2398 trans->Append(stmt);
2399
2400 // Disable all old-faction specific quests
2401 for (auto const& [questID, quest] : sObjectMgr->GetQuestTemplates())
2402 {
2403 uint32 newRaceMask = (newTeam == TEAM_ALLIANCE) ? RACEMASK_ALLIANCE : RACEMASK_HORDE;
2404
2405 if (quest->GetAllowableRaces() && !(quest->GetAllowableRaces() & newRaceMask))
2406 {
2408 stmt->SetData(0, quest->GetQuestId());
2409 stmt->SetData(1, lowGuid);
2410 trans->Append(stmt);
2411 }
2412 }
2413
2414 // Spell conversion
2415 for (auto const& [spell_alliance, spell_horde] : sObjectMgr->FactionChangeSpells)
2416 {
2417 stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_CHAR_SPELL_BY_SPELL);
2418 stmt->SetData(0, lowGuid);
2419 stmt->SetData(1, (newTeam == TEAM_ALLIANCE ? spell_alliance : spell_horde));
2420 trans->Append(stmt);
2421
2422 stmt = CharacterDatabase.GetPreparedStatement(CHAR_UPD_CHAR_SPELL_FACTION_CHANGE);
2423 stmt->SetData(0, (newTeam == TEAM_ALLIANCE ? spell_alliance : spell_horde));
2424 stmt->SetData(1, (newTeam == TEAM_ALLIANCE ? spell_horde : spell_alliance));
2425 stmt->SetData(2, lowGuid);
2426 trans->Append(stmt);
2427 }
2428
2429 // Reputation conversion
2430 for (auto const& [reputation_alliance, reputation_horde] : sObjectMgr->FactionChangeReputation)
2431 {
2432 uint32 newReputation = (newTeam == TEAM_ALLIANCE) ? reputation_alliance : reputation_horde;
2433 uint32 oldReputation = (newTeam == TEAM_ALLIANCE) ? reputation_horde : reputation_alliance;
2434
2435 // select old standing set in db
2436 stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_CHAR_REP_BY_FACTION);
2437 stmt->SetData(0, oldReputation);
2438 stmt->SetData(1, lowGuid);
2439
2440 PreparedQueryResult result = CharacterDatabase.Query(stmt);
2441 if (!result)
2442 continue;
2443
2444 fields = result->Fetch();
2445 int32 oldDBRep = fields[0].Get<int32>();
2446 FactionEntry const* factionEntry = sFactionStore.LookupEntry(oldReputation);
2447
2448 // old base reputation
2449 int32 oldBaseRep = sObjectMgr->GetBaseReputationOf(factionEntry, oldRace, playerClass);
2450
2451 // new base reputation
2452 int32 newBaseRep = sObjectMgr->GetBaseReputationOf(sFactionStore.LookupEntry(newReputation), factionChangeInfo->Race, playerClass);
2453
2454 // final reputation shouldnt change
2455 int32 FinalRep = oldDBRep + oldBaseRep;
2456 int32 newDBRep = FinalRep - newBaseRep;
2457
2458 stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_CHAR_REP_BY_FACTION);
2459 stmt->SetData(0, newReputation);
2460 stmt->SetData(1, lowGuid);
2461 trans->Append(stmt);
2462
2463 stmt = CharacterDatabase.GetPreparedStatement(CHAR_UPD_CHAR_REP_FACTION_CHANGE);
2464 stmt->SetData(0, uint16(newReputation));
2465 stmt->SetData(1, newDBRep);
2466 stmt->SetData(2, uint16(oldReputation));
2467 stmt->SetData(3, lowGuid);
2468 trans->Append(stmt);
2469 }
2470
2471 // Title conversion
2472 if (!knownTitlesStr.empty())
2473 {
2474 std::array<uint32, KNOWN_TITLES_SIZE * 2> knownTitles;
2475
2476 for (uint32 index = 0; index < knownTitles.size(); ++index)
2477 {
2478 Optional<uint32> thisMask;
2479 if (index < tokens.size())
2480 thisMask = Acore::StringTo<uint32>(tokens[index]);
2481
2482 if (thisMask)
2483 knownTitles[index] = *thisMask;
2484 else
2485 {
2486 LOG_WARN("entities.player", "{} has invalid title data '{}' at index {} - skipped, this may result in titles being lost",
2487 GetPlayerInfo(), (index < tokens.size()) ? std::string(tokens[index]) : "<none>", index);
2488
2489 knownTitles[index] = 0;
2490 }
2491 }
2492
2493 for (auto const& [title_alliance, title_horde] : sObjectMgr->FactionChangeTitles)
2494 {
2495 CharTitlesEntry const* atitleInfo = sCharTitlesStore.LookupEntry(title_alliance);
2496 CharTitlesEntry const* htitleInfo = sCharTitlesStore.LookupEntry(title_horde);
2497
2498 // new team
2499 if (newTeam == TEAM_ALLIANCE)
2500 {
2501 uint32 bitIndex = htitleInfo->bit_index;
2502 uint32 index = bitIndex / 32;
2503 uint32 old_flag = 1 << (bitIndex % 32);
2504 uint32 new_flag = 1 << (atitleInfo->bit_index % 32);
2505
2506 if (knownTitles[index] & old_flag)
2507 {
2508 knownTitles[index] &= ~old_flag;
2509 // use index of the new title
2510 knownTitles[atitleInfo->bit_index / 32] |= new_flag;
2511 }
2512 }
2513 else
2514 {
2515 uint32 bitIndex = atitleInfo->bit_index;
2516 uint32 index = bitIndex / 32;
2517 uint32 old_flag = 1 << (bitIndex % 32);
2518 uint32 new_flag = 1 << (htitleInfo->bit_index % 32);
2519
2520 if (knownTitles[index] & old_flag)
2521 {
2522 knownTitles[index] &= ~old_flag;
2523 // use index of the new title
2524 knownTitles[htitleInfo->bit_index / 32] |= new_flag;
2525 }
2526 }
2527
2528 std::ostringstream ss;
2529 for (uint32 mask : knownTitles)
2530 ss << mask << ' ';
2531
2532 stmt = CharacterDatabase.GetPreparedStatement(CHAR_UPD_CHAR_TITLES_FACTION_CHANGE);
2533 stmt->SetData(0, ss.str().c_str());
2534 stmt->SetData(1, lowGuid);
2535 trans->Append(stmt);
2536
2537 // unset any currently chosen title
2538 stmt = CharacterDatabase.GetPreparedStatement(CHAR_RES_CHAR_TITLES_FACTION_CHANGE);
2539 stmt->SetData(0, lowGuid);
2540 trans->Append(stmt);
2541 }
2542 }
2543 }
2544 }
2545
2546 // Re-check all achievement criterias
2547 stmt = CharacterDatabase.GetPreparedStatement(CHAR_UPD_ADD_AT_LOGIN_FLAG);
2549 stmt->SetData(1, lowGuid);
2550 trans->Append(stmt);
2551
2552 CharacterDatabase.CommitTransaction(trans);
2553
2554 LOG_DEBUG("entities.player", "{} (IP: {}) changed race from {} to {}", GetPlayerInfo(), GetRemoteAddress(), oldRace, factionChangeInfo->Race);
2555
2556 SendCharFactionChange(RESPONSE_SUCCESS, factionChangeInfo.get());
2557}
#define LOG_WARN(filterType__,...)
Definition: Log.h:160
std::optional< T > Optional
Optional helper class to wrap optional values within.
Definition: Optional.h:24
DBCStorage< CharTitlesEntry > sCharTitlesStore(CharTitlesEntryfmt)
DBCStorage< FactionEntry > sFactionStore(FactionEntryfmt)
TaxiMask sAllianceTaxiNodesMask
Definition: DBCStores.cpp:179
LFGDungeonEntry const * GetZoneLFGDungeonEntry(std::string const &zoneName, LocaleConstant locale)
Definition: DBCStores.cpp:867
TaxiPathSetBySource sTaxiPathSetBySource
Definition: DBCStores.cpp:183
TaxiPathNodesByPath sTaxiPathNodesByPath
Definition: DBCStores.cpp:187
TaxiMask sDeathKnightTaxiNodesMask
Definition: DBCStores.cpp:180
DBCStorage< AreaTableEntry > sAreaTableStore(AreaTableEntryfmt)
TaxiMask sHordeTaxiNodesMask
Definition: DBCStores.cpp:178
@ CONFIG_CHANGE_FACTION_MAX_MONEY
Definition: IWorld.h:418
@ CONFIG_ALLOW_TWO_SIDE_INTERACTION_GUILD
Definition: IWorld.h:76
@ PHASEMASK_NORMAL
Definition: Object.h:59
#define KNOWN_TITLES_SIZE
Definition: Player.h:553
@ AT_LOGIN_RESURRECT
Definition: Player.h:611
@ AT_LOGIN_CHANGE_RACE
Definition: Player.h:607
@ AT_LOGIN_CHECK_ACHIEVS
Definition: Player.h:610
@ AT_LOGIN_CHANGE_FACTION
Definition: Player.h:606
@ CHAR_DEL_CHAR_SOCIAL_BY_FRIEND
Definition: CharacterDatabase.h:393
@ CHAR_UPD_CHAR_INVENTORY_FACTION_CHANGE
Definition: CharacterDatabase.h:396
@ CHAR_DEL_CHAR_QUESTSTATUS_REWARDED_BY_QUEST
Definition: CharacterDatabase.h:439
@ CHAR_UPD_CHAR_QUESTSTATUS_REWARDED_FACTION_CHANGE
Definition: CharacterDatabase.h:440
@ CHAR_DEL_CHAR_SKILL_LANGUAGES
Definition: CharacterDatabase.h:387
@ CHAR_UPD_CHAR_ACHIEVEMENT
Definition: CharacterDatabase.h:395
@ CHAR_DEL_CHAR_DECLINED_NAME
Definition: CharacterDatabase.h:384
@ CHAR_INS_PLAYER_HOMEBIND
Definition: CharacterDatabase.h:240
@ CHAR_INS_CHAR_SKILL_LANGUAGE
Definition: CharacterDatabase.h:388
@ CHAR_UPD_CHAR_SPELL_FACTION_CHANGE
Definition: CharacterDatabase.h:398
@ CHAR_UPD_CHAR_TAXI_PATH
Definition: CharacterDatabase.h:389
@ CHAR_UPD_CHAR_TAXIMASK
Definition: CharacterDatabase.h:390
@ CHAR_DEL_PLAYER_HOMEBIND
Definition: CharacterDatabase.h:242
@ CHAR_SEL_CHAR_REP_BY_FACTION
Definition: CharacterDatabase.h:399
@ CHAR_DEL_CHAR_SPELL_BY_SPELL
Definition: CharacterDatabase.h:397
@ CHAR_UPD_CHAR_QUESTSTATUS_REWARDED_ACTIVE_BY_QUEST
Definition: CharacterDatabase.h:442
@ CHAR_DEL_CHAR_ACHIEVEMENT_BY_ACHIEVEMENT
Definition: CharacterDatabase.h:394
@ CHAR_DEL_CHAR_QUESTSTATUS
Definition: CharacterDatabase.h:391
@ CHAR_UPD_CHAR_REP_FACTION_CHANGE
Definition: CharacterDatabase.h:401
@ CHAR_UPD_CHAR_RACE
Definition: CharacterDatabase.h:386
@ CHAR_UPD_CHAR_TITLES_FACTION_CHANGE
Definition: CharacterDatabase.h:402
@ CHAR_DEL_CHAR_REP_BY_FACTION
Definition: CharacterDatabase.h:400
@ CHAR_UPD_ADD_AT_LOGIN_FLAG
Definition: CharacterDatabase.h:274
@ CHAR_RES_CHAR_TITLES_FACTION_CHANGE
Definition: CharacterDatabase.h:403
@ CHAR_UPD_CHAR_QUESTSTATUS_REWARDED_ACTIVE
Definition: CharacterDatabase.h:441
@ CHAR_DEL_CHAR_SOCIAL_BY_GUID
Definition: CharacterDatabase.h:392
@ CHAR_CREATE_CHARACTER_IN_GUILD
Definition: SharedDefines.h:3388
@ CHAR_CREATE_CHARACTER_DELETE_MAIL
Definition: SharedDefines.h:3392
@ CHAR_CREATE_CHARACTER_GOLD_LIMIT
Definition: SharedDefines.h:3396
@ CHAR_CREATE_CHARACTER_ARENA_LEADER
Definition: SharedDefines.h:3391
@ CHAR_CREATE_CHARACTER_SWAP_FACTION
Definition: SharedDefines.h:3393
@ CHAR_CREATE_CHARACTER_RACE_ONLY
Definition: SharedDefines.h:3394
#define RACEMASK_HORDE
Definition: SharedDefines.h:107
@ RACE_TROLL
Definition: SharedDefines.h:78
@ RACE_UNDEAD_PLAYER
Definition: SharedDefines.h:75
@ RACE_ORC
Definition: SharedDefines.h:72
@ RACE_DRAENEI
Definition: SharedDefines.h:81
@ RACE_NIGHTELF
Definition: SharedDefines.h:74
@ RACE_BLOODELF
Definition: SharedDefines.h:80
@ RACE_DWARF
Definition: SharedDefines.h:73
@ RACE_GNOME
Definition: SharedDefines.h:77
@ RACE_HUMAN
Definition: SharedDefines.h:71
@ RACE_TAUREN
Definition: SharedDefines.h:76
#define RACEMASK_ALLIANCE
Definition: SharedDefines.h:103
std::array< uint32, TaxiMaskSize > TaxiMask
Definition: DBCStructure.h:2248
std::vector< TaxiPathNodeEntry const * > TaxiPathNodeList
Definition: DBCStructure.h:2244
std::map< uint32, TaxiPathEntry const * > TaxiPathSetForSource
Definition: DBCStructure.h:2241
static constexpr std::size_t TaxiMaskSize
Definition: DBCStructure.h:2247
std::vector< std::string_view > Tokenize(std::string_view str, char sep, bool keepEmpty)
Definition: Tokenize.cpp:20
AuctionEntryMap const & GetAuctions()
Definition: AuctionHouseMgr.h:146
uint8 Class
Definition: CharacterCache.h:32
uint8 Level
Definition: CharacterCache.h:35
ObjectGuid::LowType GuildId
Definition: CharacterCache.h:37
std::string Name
Definition: CharacterCache.h:30
uint8 MailCount
Definition: CharacterCache.h:36
float GetPositionZ() const
Definition: Position.h:119
Definition: Position.h:251
void WorldRelocate(const WorldLocation &loc)
Definition: Position.h:259
static void OfflineResurrect(ObjectGuid const guid, CharacterDatabaseTransaction trans)
Definition: Player.cpp:4568
static void LeaveAllArenaTeams(ObjectGuid guid)
Definition: Player.cpp:10176
static void SavePositionInDB(uint32 mapid, float x, float y, float z, float o, uint32 zone, ObjectGuid guid)
Definition: PlayerMisc.cpp:84
Definition: DBCStructure.h:518
char const * area_name[16]
Definition: DBCStructure.h:526
Definition: DBCStructure.h:631
uint32 bit_index
Definition: DBCStructure.h:638
Definition: DBCStructure.h:906
Definition: DBCStructure.h:1244
uint32 MinLevel
Definition: DBCStructure.h:1248
Definition: DBCStructure.h:1964
uint32 ID
Definition: DBCStructure.h:1965
Definition: DBCStructure.h:1972
float y
Definition: DBCStructure.h:1978
float x
Definition: DBCStructure.h:1977
uint32 mapid
Definition: DBCStructure.h:1976
float z
Definition: DBCStructure.h:1979

References AreaTableEntry::area_name, AT_LOGIN_CHANGE_FACTION, AT_LOGIN_CHANGE_RACE, AT_LOGIN_CHECK_ACHIEVS, AT_LOGIN_RESURRECT, CharTitlesEntry::bit_index, CHAR_CREATE_CHARACTER_ARENA_LEADER, CHAR_CREATE_CHARACTER_DELETE_MAIL, CHAR_CREATE_CHARACTER_GOLD_LIMIT, CHAR_CREATE_CHARACTER_IN_GUILD, CHAR_CREATE_CHARACTER_RACE_ONLY, CHAR_CREATE_CHARACTER_SWAP_FACTION, CHAR_CREATE_ERROR, CHAR_CREATE_NAME_IN_USE, CHAR_DEL_CHAR_ACHIEVEMENT_BY_ACHIEVEMENT, CHAR_DEL_CHAR_DECLINED_NAME, CHAR_DEL_CHAR_QUESTSTATUS, CHAR_DEL_CHAR_QUESTSTATUS_REWARDED_BY_QUEST, CHAR_DEL_CHAR_REP_BY_FACTION, CHAR_DEL_CHAR_SKILL_LANGUAGES, CHAR_DEL_CHAR_SOCIAL_BY_FRIEND, CHAR_DEL_CHAR_SOCIAL_BY_GUID, CHAR_DEL_CHAR_SPELL_BY_SPELL, CHAR_DEL_PLAYER_HOMEBIND, CHAR_INS_CHAR_SKILL_LANGUAGE, CHAR_INS_PLAYER_HOMEBIND, CHAR_NAME_NO_NAME, CHAR_NAME_SUCCESS, CHAR_RES_CHAR_TITLES_FACTION_CHANGE, CHAR_SEL_CHAR_REP_BY_FACTION, CHAR_UPD_ADD_AT_LOGIN_FLAG, CHAR_UPD_CHAR_ACHIEVEMENT, CHAR_UPD_CHAR_INVENTORY_FACTION_CHANGE, CHAR_UPD_CHAR_NAME_AT_LOGIN, CHAR_UPD_CHAR_QUESTSTATUS_REWARDED_ACTIVE, CHAR_UPD_CHAR_QUESTSTATUS_REWARDED_ACTIVE_BY_QUEST, CHAR_UPD_CHAR_QUESTSTATUS_REWARDED_FACTION_CHANGE, CHAR_UPD_CHAR_RACE, CHAR_UPD_CHAR_REP_FACTION_CHANGE, CHAR_UPD_CHAR_SPELL_FACTION_CHANGE, CHAR_UPD_CHAR_TAXI_PATH, CHAR_UPD_CHAR_TAXIMASK, CHAR_UPD_CHAR_TITLES_FACTION_CHANGE, CharacterDatabase, ObjectMgr::CheckPlayerName(), CharacterCacheEntry::Class, CLASS_DEATH_KNIGHT, CONFIG_ALLOW_TWO_SIDE_ADD_FRIEND, CONFIG_ALLOW_TWO_SIDE_INTERACTION_GUILD, CONFIG_CHANGE_FACTION_MAX_MONEY, CONFIG_CHARACTER_CREATING_DISABLED_RACEMASK, Player::Customize(), Field::Get(), GetAccountId(), AuctionHouseObject::GetAuctions(), WorldLocation::GetMapId(), GetPlayerInfo(), Position::GetPositionX(), Position::GetPositionY(), Position::GetPositionZ(), GetRemoteAddress(), GetSecurity(), GetSessionDbLocaleIndex(), GetZoneLFGDungeonEntry(), CharacterCacheEntry::GuildId, TaxiPathEntry::ID, AccountMgr::IsPlayerAccount(), KNOWN_TITLES_SIZE, Player::LeaveAllArenaTeams(), CharacterCacheEntry::Level, LOG_DEBUG, LOG_INFO, LOG_WARN, CharacterCacheEntry::MailCount, TaxiPathNodeEntry::mapid, LFGDungeonEntry::MinLevel, CharacterCacheEntry::Name, normalizePlayerName(), Player::OfflineResurrect(), PHASEMASK_NORMAL, CharacterCacheEntry::Race, RACE_BLOODELF, RACE_DRAENEI, RACE_DWARF, RACE_GNOME, RACE_HUMAN, RACE_NIGHTELF, RACE_ORC, RACE_TAUREN, RACE_TROLL, RACE_UNDEAD_PLAYER, RACEMASK_ALLIANCE, RACEMASK_HORDE, RESPONSE_SUCCESS, sAllianceTaxiNodesMask, sAreaTableStore, sArenaTeamMgr, sAuctionMgr, Player::SavePositionInDB(), sCharacterCache, sCharTitlesStore, sDeathKnightTaxiNodesMask, SendCharFactionChange(), PreparedStatementBase::SetData(), sFactionStore, sGuildMgr, sHordeTaxiNodesMask, sMapMgr, sObjectMgr, sTaxiPathNodesByPath, sTaxiPathSetBySource, sWorld, TaxiMaskSize, TEAM_ALLIANCE, TEAM_HORDE, Player::TeamIdForRace(), Acore::Tokenize(), WorldLocation::WorldRelocate(), TaxiPathNodeEntry::x, TaxiPathNodeEntry::y, and TaxiPathNodeEntry::z.

Referenced by HandleCharFactionOrRaceChange().

◆ HandleCharRenameCallBack()

void WorldSession::HandleCharRenameCallBack ( std::shared_ptr< CharacterRenameInfo renameInfo,
PreparedQueryResult  result 
)
1371{
1372 if (!result)
1373 {
1374 SendCharRename(CHAR_CREATE_ERROR, renameInfo.get());
1375 return;
1376 }
1377
1378 Field* fields = result->Fetch();
1379
1380 ObjectGuid::LowType guidLow = fields[0].Get<uint32>();
1381 std::string oldName = fields[1].Get<std::string>();
1382 uint16 atLoginFlags = fields[2].Get<uint16>();
1383
1384 if (!(atLoginFlags & AT_LOGIN_RENAME))
1385 {
1386 SendCharRename(CHAR_CREATE_ERROR, renameInfo.get());
1387 return;
1388 }
1389
1390 atLoginFlags &= ~AT_LOGIN_RENAME;
1391
1392 // pussywizard:
1393 if (ObjectAccessor::FindConnectedPlayer(ObjectGuid::Create<HighGuid::Player>(guidLow)) || sWorld->FindOfflineSessionForCharacterGUID(guidLow))
1394 {
1395 SendCharRename(CHAR_CREATE_ERROR, renameInfo.get());
1396 return;
1397 }
1398
1399 // Update name and at_login flag in the db
1401 stmt->SetData(0, renameInfo->Name);
1402 stmt->SetData(1, atLoginFlags);
1403 stmt->SetData(2, guidLow);
1404 CharacterDatabase.Execute(stmt);
1405
1406 // Removed declined name from db
1407 if (sWorld->getBoolConfig(CONFIG_DECLINED_NAMES_USED))
1408 {
1409 stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_DECLINED_NAME);
1410 stmt->SetData(0, guidLow);
1411 CharacterDatabase.Execute(stmt);
1412 }
1413
1414 LOG_INFO("entities.player.character", "Account: {} (IP: {}), Character [{}] (guid: {}) Changed name to: {}", GetAccountId(), GetRemoteAddress(), oldName, guidLow, renameInfo->Name);
1415
1416 SendCharRename(RESPONSE_SUCCESS, renameInfo.get());
1417
1418 // xinef: update global data
1419 sCharacterCache->UpdateCharacterData(renameInfo->Guid, renameInfo->Name);
1420}
@ AT_LOGIN_RENAME
Definition: Player.h:600
void SendCharRename(ResponseCodes result, CharacterRenameInfo const *renameInfo)
Definition: CharacterHandler.cpp:2573

References AT_LOGIN_RENAME, CHAR_CREATE_ERROR, CHAR_DEL_DECLINED_NAME, CHAR_UPD_CHAR_NAME_AT_LOGIN, CharacterDatabase, CONFIG_DECLINED_NAMES_USED, ObjectAccessor::FindConnectedPlayer(), Field::Get(), GetAccountId(), GetRemoteAddress(), LOG_INFO, RESPONSE_SUCCESS, sCharacterCache, SendCharRename(), PreparedStatementBase::SetData(), and sWorld.

Referenced by HandleCharRenameOpcode().

◆ HandleCharRenameOpcode()

void WorldSession::HandleCharRenameOpcode ( WorldPacket recvData)
1338{
1339 std::shared_ptr<CharacterRenameInfo> renameInfo = std::make_shared<CharacterRenameInfo>();
1340
1341 recvData >> renameInfo->Guid
1342 >> renameInfo->Name;
1343
1344 // prevent character rename to invalid name
1345 if (!normalizePlayerName(renameInfo->Name))
1346 {
1347 SendCharRename(CHAR_NAME_NO_NAME, renameInfo.get());
1348 return;
1349 }
1350
1351 uint8 res = ObjectMgr::CheckPlayerName(renameInfo->Name, true);
1352 if (res != CHAR_NAME_SUCCESS)
1353 {
1354 SendCharRename(ResponseCodes(res), renameInfo.get());
1355 return;
1356 }
1357
1358 // Ensure that the character belongs to the current account, that rename at login is enabled
1359 // and that there is no character with the desired new name
1361
1362 stmt->SetData(0, renameInfo->Guid.GetCounter());
1363 stmt->SetData(1, GetAccountId());
1364 stmt->SetData(2, renameInfo->Name);
1365
1367 .WithPreparedCallback(std::bind(&WorldSession::HandleCharRenameCallBack, this, renameInfo, std::placeholders::_1)));
1368}
@ CHAR_SEL_FREE_NAME
Definition: CharacterDatabase.h:50
void HandleCharRenameCallBack(std::shared_ptr< CharacterRenameInfo > renameInfo, PreparedQueryResult result)
Definition: CharacterHandler.cpp:1370

References _queryProcessor, AsyncCallbackProcessor< T >::AddCallback(), CHAR_NAME_NO_NAME, CHAR_NAME_SUCCESS, CHAR_SEL_FREE_NAME, CharacterDatabase, ObjectMgr::CheckPlayerName(), GetAccountId(), HandleCharRenameCallBack(), normalizePlayerName(), SendCharRename(), and PreparedStatementBase::SetData().

Referenced by OpcodeTable::Initialize().

◆ HandleChatIgnoredOpcode()

void WorldSession::HandleChatIgnoredOpcode ( WorldPacket recvPacket)
799{
800 ObjectGuid iguid;
801 uint8 unk;
802
803 recvData >> iguid;
804 recvData >> unk; // probably related to spam reporting
805
807 if (!player)
808 return;
809
810 WorldPacket data;
812 player->GetSession()->SendPacket(&data);
813}
@ CHAT_MSG_IGNORED
Definition: SharedDefines.h:3177
@ LANG_UNIVERSAL
Definition: SharedDefines.h:735
static std::size_t BuildChatPacket(WorldPacket &data, ChatMsg chatType, Language language, ObjectGuid senderGUID, ObjectGuid receiverGUID, std::string_view message, uint8 chatTag, std::string const &senderName="", std::string const &receiverName="", uint32 achievementId=0, bool gmMessage=false, std::string const &channelName="")
Definition: Chat.cpp:264

References _player, ChatHandler::BuildChatPacket(), CHAT_MSG_IGNORED, ObjectAccessor::FindConnectedPlayer(), GetPlayer(), Player::GetSession(), LANG_UNIVERSAL, and SendPacket().

Referenced by OpcodeTable::Initialize().

◆ HandleClearChannelWatch()

void WorldSession::HandleClearChannelWatch ( WorldPacket recvPacket)
324{
325 std::string channelName;
326 recvPacket >> channelName;
327
328 if (channelName.empty())
329 return;
330
332 if (Channel* channel = cMgr->GetChannel(channelName, nullptr, false))
333 channel->RemoveWatching(GetPlayer());
334}

References ChannelMgr::forTeam(), GetPlayer(), and GetTeamId().

Referenced by OpcodeTable::Initialize().

◆ HandleClearTradeItemOpcode()

void WorldSession::HandleClearTradeItemOpcode ( WorldPacket recvPacket)
725{
726 uint8 tradeSlot;
727 recvPacket >> tradeSlot;
728
729 TradeData* my_trade = _player->m_trade;
730 if (!my_trade)
731 return;
732
733 // invalid slot number
734 if (tradeSlot >= TRADE_SLOT_COUNT)
735 return;
736
737 my_trade->SetItem(TradeSlots(tradeSlot), nullptr);
738}
@ TRADE_SLOT_COUNT
Definition: TradeData.h:29
void SetItem(TradeSlots slot, Item *item)
Definition: TradeData.cpp:54

References _player, Player::m_trade, TradeData::SetItem(), and TRADE_SLOT_COUNT.

Referenced by OpcodeTable::Initialize().

◆ HandleClientCastFlags()

void WorldSession::HandleClientCastFlags ( WorldPacket recvPacket,
uint8  castFlags,
SpellCastTargets targets 
)
36{
37 // some spell cast packet including more data (for projectiles?)
38 if (castFlags & 0x02)
39 {
40 // not sure about these two
41 float elevation, speed;
42 recvPacket >> elevation;
43 recvPacket >> speed;
44
45 targets.SetElevation(elevation);
46 targets.SetSpeed(speed);
47
48 uint8 hasMovementData;
49 recvPacket >> hasMovementData;
50 if (hasMovementData)
51 {
52 recvPacket.SetOpcode(recvPacket.read<uint32>());
53 HandleMovementOpcodes(recvPacket);
54 }
55 }
56}
void SetOpcode(uint16 opcode)
Definition: WorldPacket.h:77
void HandleMovementOpcodes(WorldPacket &recvPacket)
Definition: MovementHandler.cpp:334
void SetSpeed(float speed)
Definition: Spell.h:171
void SetElevation(float elevation)
Definition: Spell.h:169
T read()
Definition: ByteBuffer.h:351

References HandleMovementOpcodes(), ByteBuffer::read(), SpellCastTargets::SetElevation(), WorldPacket::SetOpcode(), and SpellCastTargets::SetSpeed().

Referenced by HandleCastSpellOpcode(), HandlePetCastSpellOpcode(), and HandleUseItemOpcode().

◆ HandleComplainOpcode()

void WorldSession::HandleComplainOpcode ( WorldPacket recvData)
1185{
1186 LOG_DEBUG("network", "WORLD: CMSG_COMPLAIN");
1187
1188 uint8 spam_type; // 0 - mail, 1 - chat
1189 ObjectGuid spammer_guid;
1190 uint32 unk1 = 0;
1191 uint32 unk2 = 0;
1192 uint32 unk3 = 0;
1193 uint32 unk4 = 0;
1194 std::string description = "";
1195 recv_data >> spam_type; // unk 0x01 const, may be spam type (mail/chat)
1196 recv_data >> spammer_guid; // player guid
1197 switch (spam_type)
1198 {
1199 case 0:
1200 recv_data >> unk1; // const 0
1201 recv_data >> unk2; // probably mail id
1202 recv_data >> unk3; // const 0
1203 break;
1204 case 1:
1205 recv_data >> unk1; // probably language
1206 recv_data >> unk2; // message type?
1207 recv_data >> unk3; // probably channel id
1208 recv_data >> unk4; // unk random value
1209 recv_data >> description; // spam description string (messagetype, channel name, player name, message)
1210 break;
1211 }
1212
1213 // NOTE: all chat messages from this spammer automatically ignored by spam reporter until logout in case chat spam.
1214 // if it's mail spam - ALL mails from this spammer automatically removed by client
1215
1216 // Complaint Received message
1218 data << uint8(0);
1219 SendPacket(&data);
1220
1221 LOG_DEBUG("network", "REPORT SPAM: type {}, {}, unk1 {}, unk2 {}, unk3 {}, unk4 {}, message {}",
1222 spam_type, spammer_guid.ToString(), unk1, unk2, unk3, unk4, description);
1223}
@ SMSG_COMPLAIN_RESULT
Definition: Opcodes.h:998

References LOG_DEBUG, SendPacket(), SMSG_COMPLAIN_RESULT, and ObjectGuid::ToString().

Referenced by OpcodeTable::Initialize().

◆ HandleCompleteCinematic()

void WorldSession::HandleCompleteCinematic ( WorldPacket recvPacket)
978{
979 // If player has sight bound to visual waypoint NPC we should remove it
981}
void EndCinematic()
Definition: CinematicMgr.cpp:74
CinematicMgr * GetCinematicMgr() const
Definition: Player.h:1373

References CinematicMgr::EndCinematic(), Player::GetCinematicMgr(), and GetPlayer().

Referenced by OpcodeTable::Initialize().

◆ HandleContactListOpcode()

void WorldSession::HandleContactListOpcode ( WorldPacket recvPacket)
30{
31 uint32 flags;
32 recv_data >> flags;
33
35}
void SendSocialList(Player *player, uint32 flags)
Definition: SocialMgr.cpp:124

References _player, Player::GetSocial(), and PlayerSocial::SendSocialList().

Referenced by OpcodeTable::Initialize().

◆ HandleCorpseMapPositionQuery()

void WorldSession::HandleCorpseMapPositionQuery ( WorldPacket recvPacket)
406{
407 LOG_DEBUG("network", "WORLD: Recv CMSG_CORPSE_MAP_POSITION_QUERY");
408
409 uint32 unk;
410 recvData >> unk;
411
413 data << float(0);
414 data << float(0);
415 data << float(0);
416 data << float(0);
417 SendPacket(&data);
418}
@ SMSG_CORPSE_MAP_POSITION_QUERY_RESPONSE
Definition: Opcodes.h:1237

References LOG_DEBUG, SendPacket(), and SMSG_CORPSE_MAP_POSITION_QUERY_RESPONSE.

Referenced by OpcodeTable::Initialize().

◆ HandleCorpseQueryOpcode()

void WorldSession::HandleCorpseQueryOpcode ( WorldPacket recvPacket)
233{
234 if (!_player->HasCorpse())
235 {
237 data << uint8(0); // corpse not found
238 SendPacket(&data);
239 return;
240 }
241
242 WorldLocation corpseLocation = _player->GetCorpseLocation();
243 uint32 corpseMapID = corpseLocation.GetMapId();
244 uint32 mapID = corpseLocation.GetMapId();
245 float x = corpseLocation.GetPositionX();
246 float y = corpseLocation.GetPositionY();
247 float z = corpseLocation.GetPositionZ();
248
249 // if corpse at different map
250 if (mapID != _player->GetMapId())
251 {
252 // search entrance map for proper show entrance
253 if (MapEntry const* corpseMapEntry = sMapStore.LookupEntry(mapID))
254 {
255 if (corpseMapEntry->IsDungeon() && corpseMapEntry->entrance_map >= 0)
256 {
257 // if corpse map have entrance
258 if (Map const* entranceMap = sMapMgr->CreateBaseMap(corpseMapEntry->entrance_map))
259 {
260 mapID = corpseMapEntry->entrance_map;
261 x = corpseMapEntry->entrance_x;
262 y = corpseMapEntry->entrance_y;
263 z = entranceMap->GetHeight(GetPlayer()->GetPhaseMask(), x, y, MAX_HEIGHT);
264 }
265 }
266 }
267 }
268
269 WorldPacket data(MSG_CORPSE_QUERY, 1 + (6 * 4));
270 data << uint8(1); // corpse found
271 data << int32(mapID);
272 data << float(x);
273 data << float(y);
274 data << float(z);
275 data << int32(corpseMapID);
276 data << uint32(0); // unknown
277 SendPacket(&data);
278}
#define MAX_HEIGHT
Definition: Map.h:164
@ MSG_CORPSE_QUERY
Definition: Opcodes.h:564
Definition: Map.h:313

References _player, Player::GetCorpseLocation(), WorldLocation::GetMapId(), GetPlayer(), Position::GetPositionX(), Position::GetPositionY(), Position::GetPositionZ(), Player::HasCorpse(), MAX_HEIGHT, MSG_CORPSE_QUERY, SendPacket(), sMapMgr, and sMapStore.

Referenced by OpcodeTable::Initialize().

◆ HandleCreatureQueryOpcode()

void WorldSession::HandleCreatureQueryOpcode ( WorldPacket recvPacket)

Only static data is sent in this packet !!!

95{
96 uint32 entry;
97 recvData >> entry;
98 ObjectGuid guid;
99 recvData >> guid;
100
101 CreatureTemplate const* ci = sObjectMgr->GetCreatureTemplate(entry);
102 if (ci)
103 {
104 std::string Name, Title;
105 Name = ci->Name;
106 Title = ci->SubName;
107
109 if (loc_idx >= 0)
110 {
111 if (CreatureLocale const* cl = sObjectMgr->GetCreatureLocale(entry))
112 {
113 ObjectMgr::GetLocaleString(cl->Name, loc_idx, Name);
114 ObjectMgr::GetLocaleString(cl->Title, loc_idx, Title);
115 }
116 }
117 // guess size
119 data << uint32(entry); // creature entry
120 data << Name;
121 data << uint8(0) << uint8(0) << uint8(0); // name2, name3, name4, always empty
122 data << Title;
123 data << ci->IconName; // "Directions" for guard, string for Icons 2.3.0
124 data << uint32(ci->type_flags); // flags
125 data << uint32(ci->type); // CreatureType.dbc
126 data << uint32(ci->family); // CreatureFamily.dbc
127 data << uint32(ci->rank); // Creature Rank (elite, boss, etc)
128 data << uint32(ci->KillCredit[0]); // new in 3.1, kill credit
129 data << uint32(ci->KillCredit[1]); // new in 3.1, kill credit
130 if (ci->GetModelByIdx(0))
131 data << uint32(ci->GetModelByIdx(0)->CreatureDisplayID); // Modelid1
132 else
133 data << uint32(0); // Modelid1
134 if (ci->GetModelByIdx(1))
135 data << uint32(ci->GetModelByIdx(1)->CreatureDisplayID); // Modelid2
136 else
137 data << uint32(0); // Modelid2
138 if (ci->GetModelByIdx(2))
139 data << uint32(ci->GetModelByIdx(2)->CreatureDisplayID); // Modelid3
140 else
141 data << uint32(0); // Modelid3
142 if (ci->GetModelByIdx(3))
143 data << uint32(ci->GetModelByIdx(3)->CreatureDisplayID); // Modelid4
144 else
145 data << uint32(0); // Modelid4
146 data << float(ci->ModHealth); // dmg/hp modifier
147 data << float(ci->ModMana); // dmg/mana modifier
148 data << uint8(ci->RacialLeader);
149
150 CreatureQuestItemList const* items = sObjectMgr->GetCreatureQuestItemList(entry);
151 if (items)
152 for (std::size_t i = 0; i < MAX_CREATURE_QUEST_ITEMS; ++i)
153 data << (i < items->size() ? uint32((*items)[i]) : uint32(0));
154 else
155 for (std::size_t i = 0; i < MAX_CREATURE_QUEST_ITEMS; ++i)
156 data << uint32(0);
157
158 data << uint32(ci->movementId); // CreatureMovementInfo.dbc
159 SendPacket(&data);
160 }
161 else
162 {
163 LOG_DEBUG("network", "WORLD: CMSG_CREATURE_QUERY - NO CREATURE INFO! ({})", guid.ToString());
165 data << uint32(entry | 0x80000000);
166 SendPacket(&data);
167 LOG_DEBUG("network", "WORLD: Sent SMSG_CREATURE_QUERY_RESPONSE");
168 }
169}
LocaleConstant
Definition: Common.h:65
std::vector< uint32 > CreatureQuestItemList
Definition: CreatureData.h:289
#define MAX_CREATURE_QUEST_ITEMS
Definition: CreatureData.h:34
@ SMSG_CREATURE_QUERY_RESPONSE
Definition: Opcodes.h:127
uint32 CreatureDisplayID
Definition: CreatureData.h:180
CreatureModel const * GetModelByIdx(uint32 idx) const
Definition: Creature.cpp:122
float ModHealth
Definition: CreatureData.h:238
float ModMana
Definition: CreatureData.h:239
uint32 type
Definition: CreatureData.h:223
uint32 rank
Definition: CreatureData.h:207
std::string SubName
Definition: CreatureData.h:193
std::string Name
Definition: CreatureData.h:192
uint32 KillCredit[MAX_KILL_CREDIT]
Definition: CreatureData.h:190
bool RacialLeader
Definition: CreatureData.h:242
uint32 type_flags
Definition: CreatureData.h:224
uint32 family
Definition: CreatureData.h:218
uint32 movementId
Definition: CreatureData.h:243
std::string IconName
Definition: CreatureData.h:194
Definition: CreatureData.h:344
static std::string_view GetLocaleString(std::vector< std::string > const &data, std::size_t locale)
Definition: ObjectMgr.h:1403

References CreatureModel::CreatureDisplayID, CreatureTemplate::family, ObjectMgr::GetLocaleString(), CreatureTemplate::GetModelByIdx(), GetSessionDbLocaleIndex(), CreatureTemplate::IconName, CreatureTemplate::KillCredit, LOG_DEBUG, MAX_CREATURE_QUEST_ITEMS, CreatureTemplate::ModHealth, CreatureTemplate::ModMana, CreatureTemplate::movementId, CreatureTemplate::Name, CreatureTemplate::RacialLeader, CreatureTemplate::rank, SendPacket(), SMSG_CREATURE_QUERY_RESPONSE, sObjectMgr, CreatureTemplate::SubName, ObjectGuid::ToString(), CreatureTemplate::type, and CreatureTemplate::type_flags.

Referenced by OpcodeTable::Initialize().

◆ HandleDelFriendOpcode()

void WorldSession::HandleDelFriendOpcode ( WorldPacket recvPacket)
92{
93 ObjectGuid FriendGUID;
94 recv_data >> FriendGUID;
95
97
98 sSocialMgr->SendFriendStatus(GetPlayer(), FRIEND_REMOVED, FriendGUID, false);
99
100 LOG_DEBUG("network", "WORLD: Sent motd (SMSG_FRIEND_STATUS)");
101}
@ FRIEND_REMOVED
Definition: SocialMgr.h:71
void RemoveFromSocialList(ObjectGuid friend_guid, SocialFlag flag)
Definition: SocialMgr.cpp:74

References _player, FRIEND_REMOVED, GetPlayer(), Player::GetSocial(), LOG_DEBUG, PlayerSocial::RemoveFromSocialList(), SOCIAL_FLAG_FRIEND, and sSocialMgr.

Referenced by OpcodeTable::Initialize().

◆ HandleDelIgnoreOpcode()

void WorldSession::HandleDelIgnoreOpcode ( WorldPacket recvPacket)
139{
140 ObjectGuid IgnoreGUID;
141 recv_data >> IgnoreGUID;
142
144 sSocialMgr->SendFriendStatus(GetPlayer(), FRIEND_IGNORE_REMOVED, IgnoreGUID, false);
145}
@ FRIEND_IGNORE_REMOVED
Definition: SocialMgr.h:82

References _player, FRIEND_IGNORE_REMOVED, GetPlayer(), Player::GetSocial(), PlayerSocial::RemoveFromSocialList(), SOCIAL_FLAG_IGNORED, and sSocialMgr.

Referenced by OpcodeTable::Initialize().

◆ HandleDestroyItemOpcode()

void WorldSession::HandleDestroyItemOpcode ( WorldPacket recvPacket)
297{
298 //LOG_DEBUG("network.opcode", "WORLD: CMSG_DESTROYITEM");
299 uint8 bag, slot, count, data1, data2, data3;
300
301 recvData >> bag >> slot >> count >> data1 >> data2 >> data3;
302
303 uint16 pos = (bag << 8) | slot;
304
305 // prevent drop unequipable items (in combat, for example) and non-empty bags
306 if (_player->IsEquipmentPos(pos) || _player->IsBagPos(pos))
307 {
308 InventoryResult msg = _player->CanUnequipItem(pos, false);
309 if (msg != EQUIP_ERR_OK)
310 {
311 _player->SendEquipError(msg, _player->GetItemByPos(pos), nullptr);
312 return;
313 }
314 }
315
316 Item* pItem = _player->GetItemByPos(bag, slot);
317 if (!pItem)
318 {
320 return;
321 }
322
324 {
326 return;
327 }
328
329 recoveryItem(pItem);
330
331 if (count)
332 {
333 uint32 i_count = count;
334 _player->DestroyItemCount(pItem, i_count, true);
335 }
336 else
337 {
338 _player->DestroyItem(bag, slot, true);
339 }
341}
@ ITEM_FLAG_NO_USER_DESTROY
Definition: ItemTemplate.h:152
@ EQUIP_ERR_CANT_DROP_SOULBOUND
Definition: Item.h:71
void SendQuestGiverStatusMultiple()
Definition: Player.cpp:7688
bool recoveryItem(Item *pItem)
Definition: ItemHandler.cpp:1688

References _player, Player::CanUnequipItem(), Player::DestroyItem(), Player::DestroyItemCount(), EQUIP_ERR_CANT_DROP_SOULBOUND, EQUIP_ERR_ITEM_NOT_FOUND, EQUIP_ERR_OK, Player::GetItemByPos(), Item::GetTemplate(), ItemTemplate::HasFlag(), Player::IsBagPos(), Player::IsEquipmentPos(), ITEM_FLAG_NO_USER_DESTROY, recoveryItem(), Player::SendEquipError(), and Player::SendQuestGiverStatusMultiple().

Referenced by OpcodeTable::Initialize().

◆ HandleDismissControlledVehicle()

void WorldSession::HandleDismissControlledVehicle ( WorldPacket recvData)
27{
28 LOG_DEBUG("network", "WORLD: Recvd CMSG_DISMISS_CONTROLLED_VEHICLE");
29
30 ObjectGuid vehicleGUID = _player->GetCharmGUID();
31
32 if (!vehicleGUID) // something wrong here...
33 {
34 recvData.rfinish(); // prevent warnings spam
35 return;
36 }
37
38 ObjectGuid guid;
39 recvData >> guid.ReadAsPacked();
40
41 // pussywizard: typical check for incomming movement packets
43 {
44 recvData.rfinish(); // prevent warnings spam
46 return;
47 }
48
49 MovementInfo mi;
50 mi.guid = guid;
51 ReadMovementInfo(recvData, &mi);
52
54
56}
bool IsDuringRemoveFromWorld() const
Definition: Unit.h:1726
void ExitVehicle(Position const *exitPosition=nullptr)
Definition: Unit.cpp:19700

References _player, Unit::ExitVehicle(), Unit::GetCharmGUID(), Object::GetGUID(), MovementInfo::guid, Unit::IsDuringRemoveFromWorld(), Object::IsInWorld(), LOG_DEBUG, WorldObject::m_movementInfo, Player::m_mover, ObjectGuid::ReadAsPacked(), ReadMovementInfo(), and ByteBuffer::rfinish().

Referenced by OpcodeTable::Initialize().

◆ HandleDismissCritter()

void WorldSession::HandleDismissCritter ( WorldPackets::Pet::DismissCritter dismissCritter)
40{
41 Unit* pet = ObjectAccessor::GetCreatureOrPetOrVehicle(*_player, packet.CritterGUID);
42
43 if (!pet)
44 {
45 LOG_DEBUG("network", "Vanitypet ({}) does not exist - player {} ({} / account: {}) attempted to dismiss it (possibly lagged out)",
46 packet.CritterGUID.ToString(), GetPlayer()->GetName(), GetPlayer()->GetGUID().ToString(), GetAccountId());
47 return;
48 }
49
50 if (_player->GetCritterGUID() == pet->GetGUID())
51 {
52 if (pet->IsCreature() && pet->ToCreature()->IsSummon())
53 pet->ToTempSummon()->UnSummon();
54 }
55}
Creature * GetCreatureOrPetOrVehicle(WorldObject const &, ObjectGuid const)
Definition: ObjectAccessor.cpp:234
virtual void UnSummon(uint32 msTime=0)
Definition: TemporarySummon.cpp:282
TempSummon * ToTempSummon()
Definition: Unit.h:1730
bool IsSummon() const
Definition: Unit.h:707
ObjectGuid GetCritterGUID() const
Definition: Unit.h:1234

References _player, WorldPackets::Pet::DismissCritter::CritterGUID, GetAccountId(), ObjectAccessor::GetCreatureOrPetOrVehicle(), Unit::GetCritterGUID(), Object::GetGUID(), GetPlayer(), Object::IsCreature(), Unit::IsSummon(), LOG_DEBUG, Object::ToCreature(), ObjectGuid::ToString(), Unit::ToTempSummon(), and TempSummon::UnSummon().

Referenced by OpcodeTable::Initialize().

◆ HandleDuelAcceptedOpcode()

void WorldSession::HandleDuelAcceptedOpcode ( WorldPacket recvPacket)
26{
27 Player* player = GetPlayer();
28 if (!player->duel || player == player->duel->Initiator || player->duel->State != DUEL_STATE_CHALLENGED)
29 return;
30
31 ObjectGuid guid;
32 recvPacket >> guid;
33
34 Player* target = player->duel->Opponent;
35 if (target->GetGuidValue(PLAYER_DUEL_ARBITER) != guid)
36 return;
37
38 LOG_DEBUG("network.opcode", "Player 1 is: {} ({})", player->GetGUID().ToString(), player->GetName());
39 LOG_DEBUG("network.opcode", "Player 2 is: {} ({})", target->GetGUID().ToString(), target->GetName());
40
41 time_t now = GameTime::GetGameTime().count();
42 player->duel->StartTime = now + 3;
43 target->duel->StartTime = now + 3;
44
45 player->duel->State = DUEL_STATE_COUNTDOWN;
46 target->duel->State = DUEL_STATE_COUNTDOWN;
47
48 player->SendDuelCountdown(3000);
49 target->SendDuelCountdown(3000);
50}
@ PLAYER_DUEL_ARBITER
Definition: UpdateFields.h:177
@ DUEL_STATE_CHALLENGED
Definition: Player.h:370
@ DUEL_STATE_COUNTDOWN
Definition: Player.h:371
ObjectGuid GetGuidValue(uint16 index) const
Definition: Object.cpp:337
void SendDuelCountdown(uint32 counter)
Definition: Player.cpp:15353
std::unique_ptr< DuelInfo > duel
Definition: Player.h:1860

References Player::duel, DUEL_STATE_CHALLENGED, DUEL_STATE_COUNTDOWN, GameTime::GetGameTime(), Object::GetGUID(), Object::GetGuidValue(), WorldObject::GetName(), GetPlayer(), LOG_DEBUG, PLAYER_DUEL_ARBITER, Player::SendDuelCountdown(), and ObjectGuid::ToString().

Referenced by OpcodeTable::Initialize().

◆ HandleDuelCancelledOpcode()

void WorldSession::HandleDuelCancelledOpcode ( WorldPacket recvPacket)
53{
54 Player* player = GetPlayer();
55
56 ObjectGuid guid;
57 recvPacket >> guid;
58
59 // no duel requested
60 if (!player->duel || player->duel->State == DUEL_STATE_COMPLETED)
61 return;
62
63 // player surrendered in a duel using /forfeit
64 if (GetPlayer()->duel->State == DUEL_STATE_IN_PROGRESS)
65 {
67 GetPlayer()->duel->Opponent->CombatStopWithPets(true);
68
69 GetPlayer()->CastSpell(GetPlayer(), 7267, true); // beg
71 return;
72 }
73
75}
@ DUEL_STATE_COMPLETED
Definition: Player.h:373
@ DUEL_STATE_IN_PROGRESS
Definition: Player.h:372
@ DUEL_WON
Definition: SharedDefines.h:3613
@ DUEL_INTERRUPTED
Definition: SharedDefines.h:3612
void DuelComplete(DuelCompleteType type)
Definition: Player.cpp:6410
SpellCastResult CastSpell(SpellCastTargets const &targets, SpellInfo const *spellInfo, CustomSpellValues const *value, TriggerCastFlags triggerFlags=TRIGGERED_NONE, Item *castItem=nullptr, AuraEffect const *triggeredByAura=nullptr, ObjectGuid originalCaster=ObjectGuid::Empty)
Definition: Unit.cpp:1167
void CombatStopWithPets(bool includingCast=false)
Definition: Unit.cpp:10423

References Unit::CastSpell(), Unit::CombatStopWithPets(), Player::duel, DUEL_INTERRUPTED, DUEL_STATE_COMPLETED, DUEL_STATE_IN_PROGRESS, DUEL_WON, Player::DuelComplete(), and GetPlayer().

Referenced by OpcodeTable::Initialize().

◆ HandleEjectPassenger()

void WorldSession::HandleEjectPassenger ( WorldPacket data)
163{
164 Vehicle* vehicle = _player->GetVehicleKit();
165 if (!vehicle)
166 {
167 data.rfinish(); // prevent warnings spam
168 LOG_ERROR("network.opcode", "HandleEjectPassenger: Player {} is not in a vehicle!", GetPlayer()->GetGUID().ToString());
169 return;
170 }
171
172 ObjectGuid guid;
173 data >> guid;
174
175 if (guid.IsPlayer())
176 {
177 Player* player = ObjectAccessor::GetPlayer(*_player, guid);
178 if (!player)
179 {
180 LOG_ERROR("network.opcode", "Player {} tried to eject player {} from vehicle, but the latter was not found in world!", GetPlayer()->GetGUID().ToString(), guid.ToString());
181 return;
182 }
183
184 if (!player->IsOnVehicle(vehicle->GetBase()))
185 {
186 LOG_ERROR("network.opcode", "Player {} tried to eject player {}, but they are not in the same vehicle", GetPlayer()->GetGUID().ToString(), guid.ToString());
187 return;
188 }
189
190 VehicleSeatEntry const* seat = vehicle->GetSeatForPassenger(player);
191 ASSERT(seat);
192 if (seat->IsEjectable())
193 player->ExitVehicle();
194 else
195 LOG_ERROR("network.opcode", "Player {} attempted to eject player {} from non-ejectable seat.", GetPlayer()->GetGUID().ToString(), guid.ToString());
196 }
197 else if (guid.IsCreature())
198 {
199 Unit* unit = ObjectAccessor::GetUnit(*_player, guid);
200 if (!unit) // creatures can be ejected too from player mounts
201 {
202 LOG_ERROR("network.opcode", "Player {} tried to eject creature guid {} from vehicle, but the latter was not found in world!", GetPlayer()->GetGUID().ToString(), guid.ToString());
203 return;
204 }
205
206 if (!unit->IsOnVehicle(vehicle->GetBase()))
207 {
208 LOG_ERROR("network.opcode", "Player {} tried to eject unit {}, but they are not in the same vehicle", GetPlayer()->GetGUID().ToString(), guid.ToString());
209 return;
210 }
211
212 VehicleSeatEntry const* seat = vehicle->GetSeatForPassenger(unit);
213 ASSERT(seat);
214 if (seat->IsEjectable())
215 {
216 ASSERT(GetPlayer() == vehicle->GetBase());
217 unit->ExitVehicle();
218 }
219 else
220 LOG_ERROR("network.opcode", "Player {} attempted to eject creature {} from non-ejectable seat.", GetPlayer()->GetGUID().ToString(), guid.ToString());
221 }
222 else
223 LOG_ERROR("network.opcode", "HandleEjectPassenger: Player {} tried to eject invalid {}", GetPlayer()->GetGUID().ToString(), guid.ToString());
224}
bool IsPlayer() const
Definition: ObjectGuid.h:168
bool IsCreature() const
Definition: ObjectGuid.h:162
bool IsOnVehicle(Unit const *vehicle) const
Definition: Unit.h:1688
Unit * GetBase() const
May be called from scripts.
Definition: Vehicle.h:37
bool IsEjectable() const
Definition: DBCStructure.h:2125

References _player, ASSERT, Unit::ExitVehicle(), Vehicle::GetBase(), GetPlayer(), ObjectAccessor::GetPlayer(), Vehicle::GetSeatForPassenger(), ObjectAccessor::GetUnit(), Unit::GetVehicleKit(), ObjectGuid::IsCreature(), VehicleSeatEntry::IsEjectable(), Unit::IsOnVehicle(), ObjectGuid::IsPlayer(), LOG_ERROR, ByteBuffer::rfinish(), and ObjectGuid::ToString().

Referenced by OpcodeTable::Initialize().

◆ HandleEmoteOpcode()

void WorldSession::HandleEmoteOpcode ( WorldPackets::Chat::EmoteClient packet)
679{
680 if (GetPlayer()->IsSpectator())
681 return;
682
683 uint32 emoteId = packet.EmoteID;
684
685 // restrict to the only emotes hardcoded in client
686 if (emoteId != EMOTE_ONESHOT_NONE && emoteId != EMOTE_ONESHOT_WAVE)
687 return;
688
690 return;
691
692 sScriptMgr->OnPlayerEmote(_player, emoteId);
693 _player->HandleEmoteCommand(emoteId);
694}
@ EMOTE_ONESHOT_NONE
Definition: SharedDefines.h:1894
@ EMOTE_ONESHOT_WAVE
Definition: SharedDefines.h:1897
void HandleEmoteCommand(uint32 emoteId)
Definition: Unit.cpp:1983
uint32 EmoteID
Definition: ChatPackets.h:46

References _player, EMOTE_ONESHOT_NONE, EMOTE_ONESHOT_WAVE, WorldPackets::Chat::EmoteClient::EmoteID, GetPlayer(), Unit::HandleEmoteCommand(), Unit::HasUnitState(), Unit::IsAlive(), sScriptMgr, and UNIT_STATE_DIED.

Referenced by OpcodeTable::Initialize().

◆ HandleEnterPlayerVehicle()

void WorldSession::HandleEnterPlayerVehicle ( WorldPacket data)
141{
142 // Read guid
143 ObjectGuid guid;
144 data >> guid;
145
146 if (Player* player = ObjectAccessor::GetPlayer(*_player, guid))
147 {
148 if (!player->GetVehicleKit())
149 return;
150 if (!player->IsInRaidWith(_player))
151 return;
152 if (!player->IsWithinDistInMap(_player, INTERACTION_DISTANCE))
153 return;
154 // Xinef:
156 return;
157
158 _player->EnterVehicle(player);
159 }
160}
void EnterVehicle(Unit *base, int8 seatId=-1)
Definition: Unit.cpp:19604
bool IsBattleArena() const
Definition: Map.h:455

References _player, Unit::EnterVehicle(), WorldObject::FindMap(), ObjectAccessor::GetPlayer(), INTERACTION_DISTANCE, and Map::IsBattleArena().

Referenced by OpcodeTable::Initialize().

◆ HandleEquipmentSetDelete()

void WorldSession::HandleEquipmentSetDelete ( WorldPacket recvData)
1804{
1805 LOG_DEBUG("network", "CMSG_EQUIPMENT_SET_DELETE");
1806
1807 uint64 setGuid;
1808 recvData.readPackGUID(setGuid);
1809
1810 _player->DeleteEquipmentSet(setGuid);
1811}
void DeleteEquipmentSet(uint64 setGuid)
Definition: Player.cpp:14624
void readPackGUID(uint64 &guid)
Definition: ByteBuffer.h:387

References _player, Player::DeleteEquipmentSet(), LOG_DEBUG, and ByteBuffer::readPackGUID().

Referenced by OpcodeTable::Initialize().

◆ HandleEquipmentSetSave()

void WorldSession::HandleEquipmentSetSave ( WorldPacket recvData)
1745{
1746 LOG_DEBUG("network", "CMSG_EQUIPMENT_SET_SAVE");
1747
1748 uint64 setGuid;
1749 recvData.readPackGUID(setGuid);
1750
1751 uint32 index;
1752 recvData >> index;
1753 if (index >= MAX_EQUIPMENT_SET_INDEX) // client set slots amount
1754 return;
1755
1756 std::string name;
1757 recvData >> name;
1758
1759 std::string iconName;
1760 recvData >> iconName;
1761
1762 EquipmentSet eqSet;
1763
1764 eqSet.Guid = setGuid;
1765 eqSet.Name = name;
1766 eqSet.IconName = iconName;
1767 eqSet.state = EQUIPMENT_SET_NEW;
1768
1769 for (uint32 i = 0; i < EQUIPMENT_SLOT_END; ++i)
1770 {
1771 ObjectGuid itemGuid;
1772 recvData >> itemGuid.ReadAsPacked();
1773
1774 // xinef: if client sends 0, it means empty slot
1775 if (!itemGuid)
1776 {
1777 eqSet.Items[i].Clear();
1778 continue;
1779 }
1780
1781 // equipment manager sends "1" (as raw GUID) for slots set to "ignore" (don't touch slot at equip set)
1782 if (itemGuid.GetRawValue() == 1)
1783 {
1784 // ignored slots saved as bit mask because we have no free special values for Items[i]
1785 eqSet.IgnoreMask |= 1 << i;
1786 continue;
1787 }
1788
1789 // xinef: some cheating checks
1791 if (!item || item->GetGUID() != itemGuid)
1792 {
1793 eqSet.Items[i].Clear();
1794 continue;
1795 }
1796
1797 eqSet.Items[i] = itemGuid;
1798 }
1799
1800 _player->SetEquipmentSet(index, eqSet);
1801}
@ EQUIPMENT_SET_NEW
Definition: Player.h:744
#define MAX_EQUIPMENT_SET_INDEX
Definition: Player.h:760
@ EQUIPMENT_SLOT_END
Definition: Player.h:694
uint64 GetRawValue() const
Definition: ObjectGuid.h:142
Definition: Player.h:749
ObjectGuid Items[EQUIPMENT_SLOT_END]
Definition: Player.h:756
std::string Name
Definition: Player.h:753
std::string IconName
Definition: Player.h:754
EquipmentSetUpdateState state
Definition: Player.h:757
uint64 Guid
Definition: Player.h:752
uint32 IgnoreMask
Definition: Player.h:755
void SetEquipmentSet(uint32 index, EquipmentSet eqset)
Definition: Player.cpp:14508

References _player, ObjectGuid::Clear(), EQUIPMENT_SET_NEW, EQUIPMENT_SLOT_END, Object::GetGUID(), Player::GetItemByPos(), ObjectGuid::GetRawValue(), EquipmentSet::Guid, EquipmentSet::IconName, EquipmentSet::IgnoreMask, INVENTORY_SLOT_BAG_0, EquipmentSet::Items, LOG_DEBUG, MAX_EQUIPMENT_SET_INDEX, EquipmentSet::Name, ObjectGuid::ReadAsPacked(), ByteBuffer::readPackGUID(), Player::SetEquipmentSet(), and EquipmentSet::state.

Referenced by OpcodeTable::Initialize().

◆ HandleEquipmentSetUse()

void WorldSession::HandleEquipmentSetUse ( WorldPacket recvData)
1814{
1815 LOG_DEBUG("network", "CMSG_EQUIPMENT_SET_USE");
1816
1817 std::vector<std::unique_ptr<SavedItem>> savedItems;
1818 uint8 errorId = 0;
1819 for (uint32 i = 0; i < EQUIPMENT_SLOT_END; ++i)
1820 {
1821 ObjectGuid itemGuid;
1822 recvData >> itemGuid.ReadAsPacked();
1823
1824 uint8 srcbag, srcslot;
1825 recvData >> srcbag >> srcslot;
1826
1827 LOG_DEBUG("entities.player.items", "Item {}: srcbag {}, srcslot {}", itemGuid.ToString(), srcbag, srcslot);
1828
1829 // check if item slot is set to "ignored" (raw value == 1), must not be unequipped then
1830 if (itemGuid.GetRawValue() == 1)
1831 continue;
1832
1833 // Only equip weapons in combat
1835 continue;
1836
1837 Item* item = nullptr;
1838 if (itemGuid)
1839 item = _player->GetItemByGuid(itemGuid);
1840
1841 uint16 dstpos = i | (INVENTORY_SLOT_BAG_0 << 8);
1842
1843 InventoryResult msg;
1845 if (uItem)
1846 {
1847 if (uItem->IsEquipped())
1848 {
1849 msg = _player->CanUnequipItem(dstpos, true);
1850 if (msg != EQUIP_ERR_OK)
1851 {
1852 _player->SendEquipError(msg, uItem, nullptr);
1853 continue;
1854 }
1855 }
1856
1857 if (!item)
1858 {
1859 ItemPosCountVec sDest;
1860 msg = _player->CanStoreItem(NULL_BAG, NULL_SLOT, sDest, uItem, false);
1861 if (msg == EQUIP_ERR_OK)
1862 {
1863 savedItems.emplace_back(std::make_unique<SavedItem>(uItem, dstpos));
1865 _player->StoreItem(sDest, uItem, true);
1866 }
1867 else
1868 {
1869 errorId = 4;
1870 for (uint8_t j = 0; j < savedItems.size(); ++j)
1871 {
1872 _player->SwapItem(savedItems[j].get()->item->GetPos(), savedItems[j].get()->dstpos);
1873 }
1874 break;
1875 }
1876
1877 continue;
1878 }
1879 }
1880
1881 if (item)
1882 {
1883 if (item->GetPos() == dstpos)
1884 continue;
1885
1886 if (!item->IsEquipped())
1887 {
1888 uint16 _candidatePos;
1889 msg = _player->CanEquipItem(NULL_SLOT, _candidatePos, item, true);
1890 if (msg != EQUIP_ERR_OK)
1891 {
1892 _player->SendEquipError(msg, item, nullptr);
1893 continue;
1894 }
1895 }
1896
1897 _player->SwapItem(item->GetPos(), dstpos);
1898 }
1899 }
1900
1902 data << uint8(errorId); // 4 - equipment swap failed - inventory is full
1903 SendPacket(&data);
1904}
@ EQUIPMENT_SLOT_MAINHAND
Definition: Player.h:690
@ EQUIPMENT_SLOT_OFFHAND
Definition: Player.h:691
@ EQUIPMENT_SLOT_RANGED
Definition: Player.h:692
@ SMSG_EQUIPMENT_SET_USE_RESULT
Definition: Opcodes.h:1268
bool IsEquipped() const
Definition: Item.cpp:790

References _player, Player::CanEquipItem(), Player::CanStoreItem(), Player::CanUnequipItem(), EQUIP_ERR_OK, EQUIPMENT_SLOT_END, EQUIPMENT_SLOT_MAINHAND, EQUIPMENT_SLOT_OFFHAND, EQUIPMENT_SLOT_RANGED, Player::GetItemByGuid(), Player::GetItemByPos(), Item::GetPos(), ObjectGuid::GetRawValue(), INVENTORY_SLOT_BAG_0, Item::IsEquipped(), Unit::IsInCombat(), LOG_DEBUG, NULL_BAG, NULL_SLOT, ObjectGuid::ReadAsPacked(), Player::RemoveItem(), Player::SendEquipError(), SendPacket(), SMSG_EQUIPMENT_SET_USE_RESULT, Player::StoreItem(), Player::SwapItem(), and ObjectGuid::ToString().

Referenced by OpcodeTable::Initialize().

◆ HandleFarSightOpcode()

void WorldSession::HandleFarSightOpcode ( WorldPacket recvData)
1245{
1246 LOG_DEBUG("network", "WORLD: CMSG_FAR_SIGHT");
1247
1248 bool apply;
1249 recvData >> apply;
1250
1251 if (apply)
1252 {
1253 LOG_DEBUG("network", "Added FarSight {} to player {}", _player->GetGuidValue(PLAYER_FARSIGHT).ToString(), _player->GetGUID().ToString());
1254 if (WorldObject* target = _player->GetViewpoint())
1255 _player->SetSeer(target);
1256 else
1257 LOG_DEBUG("network.opcode", "Player {} requests non-existing seer {}", _player->GetName(), _player->GetGuidValue(PLAYER_FARSIGHT).ToString());
1258 }
1259 else
1260 {
1261 WorldObject* newFarsightobject = nullptr;
1262 if (WorldObject* viewpoint = _player->GetViewpoint())
1263 {
1264 if (DynamicObject* viewpointDynamicObject = viewpoint->ToDynObject())
1265 {
1266 newFarsightobject = ObjectAccessor::GetUnit(*viewpointDynamicObject, viewpointDynamicObject->GetOldFarsightGUID());
1267 }
1268 else if (DynamicObject* viewpointDynamicObject = _player->GetDynObject(_player->GetUInt32Value(UNIT_CHANNEL_SPELL)))
1269 {
1270 if (viewpointDynamicObject->IsViewpoint() && viewpointDynamicObject->GetCasterGUID() == _player->GetGUID())
1271 {
1272 newFarsightobject = viewpointDynamicObject;
1273 }
1274 }
1275 }
1276
1277 if (newFarsightobject)
1278 {
1279 LOG_DEBUG("network", "Player {} set vision to old farsight {}", _player->GetGUID().ToString(), newFarsightobject->GetGUID().ToString());
1281 _player->SetViewpoint(newFarsightobject, true);
1282 }
1283 else
1284 {
1285 LOG_DEBUG("network", "Player {} set vision to self", _player->GetGUID().ToString());
1287 }
1288 }
1289
1291}
@ PLAYER_FARSIGHT
Definition: UpdateFields.h:334
@ UNIT_CHANNEL_SPELL
Definition: UpdateFields.h:94
void apply(T *val)
Definition: ByteConverter.h:40
Definition: DynamicObject.h:35
DynamicObject * ToDynObject()
Definition: Object.h:218
Definition: Object.h:405
void SetSeer(WorldObject *target)
Definition: Player.h:2331
void UpdateVisibilityForPlayer(bool mapChange=false)
Definition: PlayerUpdates.cpp:1542
void SetViewpoint(WorldObject *target, bool apply)
Definition: Player.cpp:13171
WorldObject * GetViewpoint() const
Definition: Player.cpp:13214
DynamicObject * GetDynObject(uint32 spellId)
Definition: Unit.cpp:6106

References _player, Unit::GetDynObject(), Object::GetGUID(), Object::GetGuidValue(), WorldObject::GetName(), GetPlayer(), Object::GetUInt32Value(), ObjectAccessor::GetUnit(), Player::GetViewpoint(), LOG_DEBUG, PLAYER_FARSIGHT, Player::SetSeer(), Player::SetViewpoint(), Object::ToDynObject(), ObjectGuid::ToString(), UNIT_CHANNEL_SPELL, and Player::UpdateVisibilityForPlayer().

Referenced by OpcodeTable::Initialize().

◆ HandleFeatherFallAck()

void WorldSession::HandleFeatherFallAck ( WorldPacket recvData)
990{
991 // no used
992 recv_data.rfinish(); // prevent warnings spam
993}

References ByteBuffer::rfinish().

Referenced by OpcodeTable::Initialize().

◆ HandleForceSpeedChangeAck()

void WorldSession::HandleForceSpeedChangeAck ( WorldPacket recvData)
612{
613 uint32 opcode = recvData.GetOpcode();
614 LOG_DEBUG("network", "WORLD: Recvd {} ({}, 0x{:X}) opcode", GetOpcodeNameForLogging(static_cast<OpcodeClient>(opcode)), opcode, opcode);
615
616 /* extract packet */
617 ObjectGuid guid;
618 uint32 unk1;
619 float newspeed;
620
621 recvData >> guid.ReadAsPacked();
622
623 // pussywizard: special check, only player mover allowed here
624 if (guid != _player->m_mover->GetGUID() || guid != _player->GetGUID())
625 {
626 recvData.rfinish(); // prevent warnings spam
627 return;
628 }
629
630 // continue parse packet
631 recvData >> unk1; // counter or moveEvent
632
633 MovementInfo movementInfo;
634 movementInfo.guid = guid;
635 ReadMovementInfo(recvData, &movementInfo);
636
637 recvData >> newspeed;
638
639 // client ACK send one packet for mounted/run case and need skip all except last from its
640 // in other cases anti-cheat check can be fail in false case
641 UnitMoveType move_type;
642 UnitMoveType force_move_type;
643
644 static char const* move_type_name[MAX_MOVE_TYPE] = { "Walk", "Run", "RunBack", "Swim", "SwimBack", "TurnRate", "Flight", "FlightBack", "PitchRate" };
645
646 switch (opcode)
647 {
649 move_type = MOVE_WALK;
650 force_move_type = MOVE_WALK;
651 break;
653 move_type = MOVE_RUN;
654 force_move_type = MOVE_RUN;
655 break;
657 move_type = MOVE_RUN_BACK;
658 force_move_type = MOVE_RUN_BACK;
659 break;
661 move_type = MOVE_SWIM;
662 force_move_type = MOVE_SWIM;
663 break;
665 move_type = MOVE_SWIM_BACK;
666 force_move_type = MOVE_SWIM_BACK;
667 break;
669 move_type = MOVE_TURN_RATE;
670 force_move_type = MOVE_TURN_RATE;
671 break;
673 move_type = MOVE_FLIGHT;
674 force_move_type = MOVE_FLIGHT;
675 break;
677 move_type = MOVE_FLIGHT_BACK;
678 force_move_type = MOVE_FLIGHT_BACK;
679 break;
681 move_type = MOVE_PITCH_RATE;
682 force_move_type = MOVE_PITCH_RATE;
683 break;
684 default:
685 LOG_ERROR("network.opcode", "WorldSession::HandleForceSpeedChangeAck: Unknown move type opcode: {}", opcode);
686 return;
687 }
688
689 sScriptMgr->AnticheatSetUnderACKmount(_player);
690
691 // skip all forced speed changes except last and unexpected
692 // in run/mounted case used one ACK and it must be skipped.m_forced_speed_changes[MOVE_RUN} store both.
693 if (_player->m_forced_speed_changes[force_move_type] > 0)
694 {
695 --_player->m_forced_speed_changes[force_move_type];
696 if (_player->m_forced_speed_changes[force_move_type] > 0)
697 return;
698 }
699
700 if (!_player->GetTransport() && std::fabs(_player->GetSpeed(move_type) - newspeed) > 0.01f)
701 {
702 if (_player->GetSpeed(move_type) > newspeed) // must be greater - just correct
703 {
704 LOG_ERROR("network.opcode", "{}SpeedChange player {} is NOT correct (must be {} instead {}), force set to correct value",
705 move_type_name[move_type], _player->GetName(), _player->GetSpeed(move_type), newspeed);
706 _player->SetSpeed(move_type, _player->GetSpeedRate(move_type), true);
707 }
708 else // must be lesser - cheating
709 {
710 LOG_INFO("network.opcode", "Player {} from account id {} kicked for incorrect speed (must be {} instead {})",
711 _player->GetName(), GetAccountId(), _player->GetSpeed(move_type), newspeed);
712 KickPlayer("Incorrect speed");
713 }
714 }
715}
#define MAX_MOVE_TYPE
Definition: UnitDefines.h:339
UnitMoveType
Definition: UnitDefines.h:327
@ MOVE_FLIGHT
Definition: UnitDefines.h:334
@ MOVE_SWIM
Definition: UnitDefines.h:331
@ MOVE_TURN_RATE
Definition: UnitDefines.h:333
@ MOVE_FLIGHT_BACK
Definition: UnitDefines.h:335
@ MOVE_SWIM_BACK
Definition: UnitDefines.h:332
@ MOVE_RUN
Definition: UnitDefines.h:329
@ MOVE_PITCH_RATE
Definition: UnitDefines.h:336
@ MOVE_RUN_BACK
Definition: UnitDefines.h:330
@ MOVE_WALK
Definition: UnitDefines.h:328
@ CMSG_FORCE_PITCH_RATE_CHANGE_ACK
Definition: Opcodes.h:1147
@ CMSG_FORCE_RUN_BACK_SPEED_CHANGE_ACK
Definition: Opcodes.h:259
@ CMSG_FORCE_TURN_RATE_CHANGE_ACK
Definition: Opcodes.h:765
@ CMSG_FORCE_FLIGHT_BACK_SPEED_CHANGE_ACK
Definition: Opcodes.h:930
@ CMSG_FORCE_SWIM_SPEED_CHANGE_ACK
Definition: Opcodes.h:261
@ CMSG_FORCE_RUN_SPEED_CHANGE_ACK
Definition: Opcodes.h:257
@ CMSG_FORCE_WALK_SPEED_CHANGE_ACK
Definition: Opcodes.h:761
@ CMSG_FORCE_FLIGHT_SPEED_CHANGE_ACK
Definition: Opcodes.h:928
@ CMSG_FORCE_SWIM_BACK_SPEED_CHANGE_ACK
Definition: Opcodes.h:763
Transport * GetTransport() const
Definition: Object.h:599
uint8 m_forced_speed_changes[MAX_MOVE_TYPE]
Definition: Player.h:2382
float GetSpeed(UnitMoveType mtype) const
Definition: Unit.cpp:14388
float GetSpeedRate(UnitMoveType mtype) const
Definition: Unit.h:1601
void SetSpeed(UnitMoveType mtype, float rate, bool forced=false)
Definition: Unit.cpp:14393

References _player, CMSG_FORCE_FLIGHT_BACK_SPEED_CHANGE_ACK, CMSG_FORCE_FLIGHT_SPEED_CHANGE_ACK, CMSG_FORCE_PITCH_RATE_CHANGE_ACK, CMSG_FORCE_RUN_BACK_SPEED_CHANGE_ACK, CMSG_FORCE_RUN_SPEED_CHANGE_ACK, CMSG_FORCE_SWIM_BACK_SPEED_CHANGE_ACK, CMSG_FORCE_SWIM_SPEED_CHANGE_ACK, CMSG_FORCE_TURN_RATE_CHANGE_ACK, CMSG_FORCE_WALK_SPEED_CHANGE_ACK, GetAccountId(), Object::GetGUID(), WorldObject::GetName(), WorldPacket::GetOpcode(), GetOpcodeNameForLogging(), Unit::GetSpeed(), Unit::GetSpeedRate(), WorldObject::GetTransport(), MovementInfo::guid, KickPlayer(), LOG_DEBUG, LOG_ERROR, LOG_INFO, Player::m_forced_speed_changes, Player::m_mover, MAX_MOVE_TYPE, MOVE_FLIGHT, MOVE_FLIGHT_BACK, MOVE_PITCH_RATE, MOVE_RUN, MOVE_RUN_BACK, MOVE_SWIM, MOVE_SWIM_BACK, MOVE_TURN_RATE, MOVE_WALK, ObjectGuid::ReadAsPacked(), ReadMovementInfo(), ByteBuffer::rfinish(), Unit::SetSpeed(), and sScriptMgr.

Referenced by OpcodeTable::Initialize().

◆ HandleGameObjectQueryOpcode()

void WorldSession::HandleGameObjectQueryOpcode ( WorldPacket recvPacket)

Only static data is sent in this packet !!!

173{
174 uint32 entry;
175 recvData >> entry;
176 ObjectGuid guid;
177 recvData >> guid;
178
179 const GameObjectTemplate* info = sObjectMgr->GetGameObjectTemplate(entry);
180 if (info)
181 {
182 std::string Name;
183 std::string IconName;
184 std::string CastBarCaption;
185
186 Name = info->name;
187 IconName = info->IconName;
188 CastBarCaption = info->castBarCaption;
189
190 LocaleConstant localeConstant = GetSessionDbLocaleIndex();
191 if (localeConstant >= LOCALE_enUS)
192 if (GameObjectLocale const* gameObjectLocale = sObjectMgr->GetGameObjectLocale(entry))
193 {
194 ObjectMgr::GetLocaleString(gameObjectLocale->Name, localeConstant, Name);
195 ObjectMgr::GetLocaleString(gameObjectLocale->CastBarCaption, localeConstant, CastBarCaption);
196 }
197
198 LOG_DEBUG("network", "WORLD: CMSG_GAMEOBJECT_QUERY '{}' - Entry: {}. ", info->name, entry);
200 data << uint32(entry);
201 data << uint32(info->type);
202 data << uint32(info->displayId);
203 data << Name;
204 data << uint8(0) << uint8(0) << uint8(0); // name2, name3, name4
205 data << IconName; // 2.0.3, string. Icon name to use instead of default icon for go's (ex: "Attack" makes sword)
206 data << CastBarCaption; // 2.0.3, string. Text will appear in Cast Bar when using GO (ex: "Collecting")
207 data << info->unk1; // 2.0.3, string
208 data.append(info->raw.data, MAX_GAMEOBJECT_DATA);
209 data << float(info->size); // go size
210
211 GameObjectQuestItemList const* items = sObjectMgr->GetGameObjectQuestItemList(entry);
212 if (items)
213 for (std::size_t i = 0; i < MAX_GAMEOBJECT_QUEST_ITEMS; ++i)
214 data << (i < items->size() ? uint32((*items)[i]) : uint32(0));
215 else
216 for (std::size_t i = 0; i < MAX_GAMEOBJECT_QUEST_ITEMS; ++i)
217 data << uint32(0);
218
219 SendPacket(&data);
220 LOG_DEBUG("network", "WORLD: Sent SMSG_GAMEOBJECT_QUERY_RESPONSE");
221 }
222 else
223 {
224 LOG_DEBUG("network", "WORLD: CMSG_GAMEOBJECT_QUERY - Missing gameobject info for ({})", guid.ToString());
226 data << uint32(entry | 0x80000000);
227 SendPacket(&data);
228 LOG_DEBUG("network", "WORLD: Sent SMSG_GAMEOBJECT_QUERY_RESPONSE");
229 }
230}
@ LOCALE_enUS
Definition: Common.h:66
std::vector< uint32 > GameObjectQuestItemList
Definition: GameObject.h:47
#define MAX_GAMEOBJECT_QUEST_ITEMS
Definition: GameObjectData.h:26
#define MAX_GAMEOBJECT_DATA
Definition: SharedDefines.h:1599
@ SMSG_GAMEOBJECT_QUERY_RESPONSE
Definition: Opcodes.h:125
Definition: GameObjectData.h:31
uint32 data[MAX_GAMEOBJECT_DATA]
Definition: GameObjectData.h:388
uint32 type
Definition: GameObjectData.h:33
std::string unk1
Definition: GameObjectData.h:38
std::string name
Definition: GameObjectData.h:35
std::string castBarCaption
Definition: GameObjectData.h:37
struct GameObjectTemplate::@227::@257 raw
float size
Definition: GameObjectData.h:39
uint32 displayId
Definition: GameObjectData.h:34
std::string IconName
Definition: GameObjectData.h:36
Definition: GameObjectData.h:674

References ByteBuffer::append(), GameObjectTemplate::castBarCaption, GameObjectTemplate::data, GameObjectTemplate::displayId, ObjectMgr::GetLocaleString(), GetSessionDbLocaleIndex(), GameObjectTemplate::IconName, LOCALE_enUS, LOG_DEBUG, MAX_GAMEOBJECT_DATA, MAX_GAMEOBJECT_QUEST_ITEMS, GameObjectTemplate::name, GameObjectTemplate::raw, SendPacket(), GameObjectTemplate::size, SMSG_GAMEOBJECT_QUERY_RESPONSE, sObjectMgr, ObjectGuid::ToString(), GameObjectTemplate::type, and GameObjectTemplate::unk1.

Referenced by OpcodeTable::Initialize().

◆ HandleGameobjectReportUse()

void WorldSession::HandleGameobjectReportUse ( WorldPacket recvPacket)
313{
314 ObjectGuid guid;
315 recvPacket >> guid;
316
317 LOG_DEBUG("network", "WORLD: Recvd CMSG_GAMEOBJ_REPORT_USE Message [{}]", guid.ToString());
318
319 // ignore for remote control state
320 if (_player->m_mover != _player)
321 return;
322
323 GameObject* go = GetPlayer()->GetMap()->GetGameObject(guid);
324 if (!go)
325 return;
326
327 // Prevent use of GameObject if it is not selectable. Fixes hack.
329 return;
330
332 return;
333
334 if (go->AI()->GossipHello(_player, true))
335 return;
336
338}
@ GO_FLAG_NOT_SELECTABLE
Definition: SharedDefines.h:1607
@ ACHIEVEMENT_CRITERIA_TYPE_USE_GAMEOBJECT
Definition: DBCEnums.h:180
virtual bool GossipHello(Player *, bool)
Definition: GameObjectAI.h:54
GameObjectAI * AI() const
Definition: GameObject.h:307
bool HasGameObjectFlag(GameObjectFlags flags) const
Definition: GameObject.h:218

References _player, ACHIEVEMENT_CRITERIA_TYPE_USE_GAMEOBJECT, GameObject::AI(), Object::GetEntry(), Map::GetGameObject(), WorldObject::GetMap(), GetPlayer(), GO_FLAG_NOT_SELECTABLE, GameObjectAI::GossipHello(), GameObject::HasGameObjectFlag(), INTERACTION_DISTANCE, GameObject::IsWithinDistInMap(), LOG_DEBUG, Player::m_mover, ObjectGuid::ToString(), and Player::UpdateAchievementCriteria().

Referenced by OpcodeTable::Initialize().

◆ HandleGameObjectUseOpcode()

void WorldSession::HandleGameObjectUseOpcode ( WorldPacket recPacket)
292{
293 ObjectGuid guid;
294 recvData >> guid;
295
296 LOG_DEBUG("network", "WORLD: Recvd CMSG_GAMEOBJ_USE Message [{}]", guid.ToString());
297
298 if (GameObject* obj = GetPlayer()->GetMap()->GetGameObject(guid))
299 {
300 if (!obj->IsWithinDistInMap(GetPlayer(), obj->GetInteractionDistance()))
301 return;
302
303 // ignore for remote control state
304 if (GetPlayer()->m_mover != GetPlayer())
305 if (!(GetPlayer()->IsOnVehicle(GetPlayer()->m_mover) || GetPlayer()->IsMounted()) && !obj->GetGOInfo()->IsUsableMounted())
306 return;
307
308 obj->Use(GetPlayer());
309 }
310}
GameObject * GetGameObject(WorldObject const &u, ObjectGuid const guid)
Definition: ObjectAccessor.cpp:184

References GetPlayer(), LOG_DEBUG, and ObjectGuid::ToString().

Referenced by OpcodeTable::Initialize().

◆ HandleGetChannelMemberCount()

void WorldSession::HandleGetChannelMemberCount ( WorldPacket recvPacket)
286{
287 std::string channelName;
288 recvPacket >> channelName;
289
290 LOG_DEBUG("chat.system", "CMSG_GET_CHANNEL_MEMBER_COUNT {} Channel: {}",
291 GetPlayerInfo(), channelName);
293 {
294 if (Channel* channel = cMgr->GetChannel(channelName, GetPlayer()))
295 {
296 LOG_DEBUG("chat.system", "SMSG_CHANNEL_MEMBER_COUNT {} Channel: {} Count: {}",
297 GetPlayerInfo(), channelName, channel->GetNumPlayers());
298
299 WorldPacket data(SMSG_CHANNEL_MEMBER_COUNT, channel->GetName().size() + 1 + 4);
300 data << channel->GetName();
301 data << uint8(channel->GetFlags());
302 data << uint32(channel->GetNumPlayers());
303 SendPacket(&data);
304 }
305 }
306}
@ SMSG_CHANNEL_MEMBER_COUNT
Definition: Opcodes.h:1011

References ChannelMgr::forTeam(), GetPlayer(), GetPlayerInfo(), GetTeamId(), LOG_DEBUG, SendPacket(), and SMSG_CHANNEL_MEMBER_COUNT.

Referenced by OpcodeTable::Initialize().

◆ HandleGetMailList()

void WorldSession::HandleGetMailList ( WorldPacket recvData)
630{
631 ObjectGuid mailbox;
632 recvData >> mailbox;
633
634 if (!CanOpenMailBox(mailbox))
635 return;
636
637 Player* player = _player;
638
639 uint8 mailsCount = 0;
640 uint32 realCount = 0;
641
642 WorldPacket data(SMSG_MAIL_LIST_RESULT, (200)); // guess size
643 data << uint32(0); // real mail's count
644 data << uint8(0); // mail's count
645 time_t cur_time = GameTime::GetGameTime().count();
646
647 for (Mail const* mail : player->GetMails())
648 {
649 // prevent client storage overflow
650 if (mailsCount >= MAX_INBOX_CLIENT_CAPACITY)
651 {
652 ++realCount;
653 continue;
654 }
655
656 // skip deleted or not delivered (deliver delay not expired) mails
657 if (mail->state == MAIL_STATE_DELETED || cur_time < mail->deliver_time || cur_time > mail->expire_time)
658 {
659 continue;
660 }
661
662 uint8 item_count = uint8(mail->items.size()); // max count is MAX_MAIL_ITEMS (12)
663
664 std::size_t next_mail_size = 2 + 4 + 1 + (mail->messageType == MAIL_NORMAL ? 8 : 4) + 4 * 8 + (mail->subject.size() + 1) + (mail->body.size() + 1) + 1 + item_count * (1 + 4 + 4 + MAX_INSPECTED_ENCHANTMENT_SLOT * 3 * 4 + 4 + 4 + 4 + 4 + 4 + 4 + 1);
665
666 if (data.wpos() + next_mail_size > MAX_NETCLIENT_PACKET_SIZE)
667 {
668 ++realCount;
669 continue;
670 }
671
672 data << uint16(next_mail_size); // Message size
673 data << uint32(mail->messageID); // Message ID
674 data << uint8(mail->messageType); // Message Type
675
676 switch (mail->messageType)
677 {
678 case MAIL_NORMAL: // sender guid
679 data << ObjectGuid::Create<HighGuid::Player>(mail->sender);
680 break;
681 case MAIL_CREATURE:
682 case MAIL_GAMEOBJECT:
683 case MAIL_AUCTION:
684 case MAIL_CALENDAR:
685 data << uint32(mail->sender); // creature/gameobject entry, auction id, calendar event id?
686 break;
687 }
688
689 // prevent client crash
690 std::string subject = mail->subject;
691 std::string body = mail->body;
692
693 if (subject.find("| |") != std::string::npos)
694 {
695 subject = "";
696 }
697 if (body.find("| |") != std::string::npos)
698 {
699 body = "";
700 }
701
702 data << uint32(mail->COD); // COD
703 data << uint32(0); // probably changed in 3.3.3
704 data << uint32(mail->stationery); // stationery (Stationery.dbc)
705 data << uint32(mail->money); // Gold
706 data << uint32(mail->checked); // flags
707 data << float(float(mail->expire_time - GameTime::GetGameTime().count()) / DAY); // Time
708 data << uint32(mail->mailTemplateId); // mail template (MailTemplate.dbc)
709 data << subject; // Subject string - once 00, when mail type = 3, max 256
710 data << body; // message? max 8000
711 data << uint8(item_count); // client limit is 0x10
712
713 for (uint8 i = 0; i < item_count; ++i)
714 {
715 Item* item = player->GetMItem(mail->items[i].item_guid);
716 // item index (0-6?)
717 data << uint8(i);
718 // item guid low?
719 data << uint32((item ? item->GetGUID().GetCounter() : 0));
720 // entry
721 data << uint32((item ? item->GetEntry() : 0));
722 for (uint8 j = 0; j < MAX_INSPECTED_ENCHANTMENT_SLOT; ++j)
723 {
724 data << uint32(item ? item->GetEnchantmentId(EnchantmentSlot(j)) : 0);
725 data << uint32(item ? item->GetEnchantmentDuration(EnchantmentSlot(j)) : 0);
726 data << uint32(item ? item->GetEnchantmentCharges(EnchantmentSlot(j)) : 0);
727 }
728 // can be negative
729 data << int32((item ? item->GetItemRandomPropertyId() : 0));
730 // unk
731 data << uint32((item ? item->GetItemSuffixFactor() : 0));
732 // stack count
733 data << uint32((item ? item->GetCount() : 0));
734 // charges
735 data << uint32((item ? item->GetSpellCharges() : 0));
736 // durability
737 data << uint32((item ? item->GetUInt32Value(ITEM_FIELD_MAXDURABILITY) : 0));
738 // durability
739 data << uint32((item ? item->GetUInt32Value(ITEM_FIELD_DURABILITY) : 0));
740 // unknown wotlk
741 data << uint8(0);
742 }
743
744 ++realCount;
745 ++mailsCount;
746 }
747
748 data.put<uint32>(0, realCount); // this will display warning about undelivered mail to player if realCount > mailsCount
749 data.put<uint8>(4, mailsCount); // set real send mails to client
750 SendPacket(&data);
751
752 // recalculate m_nextMailDelivereTime and unReadMails
754}
constexpr auto DAY
Definition: Common.h:49
#define MAX_NETCLIENT_PACKET_SIZE
Definition: Common.h:43
#define MAX_INBOX_CLIENT_CAPACITY
Definition: MailHandler.cpp:35
@ ITEM_FIELD_DURABILITY
Definition: UpdateFields.h:69
@ ITEM_FIELD_MAXDURABILITY
Definition: UpdateFields.h:70
EnchantmentSlot
Definition: Item.h:168
@ MAX_INSPECTED_ENCHANTMENT_SLOT
Definition: Item.h:176
@ MAIL_STATE_DELETED
Definition: Mail.h:71
@ MAIL_AUCTION
Definition: Mail.h:39
@ MAIL_GAMEOBJECT
Definition: Mail.h:41
@ MAIL_CREATURE
Definition: Mail.h:40
@ MAIL_CALENDAR
Definition: Mail.h:42
@ MAIL_NORMAL
Definition: Mail.h:38
@ SMSG_MAIL_LIST_RESULT
Definition: Opcodes.h:601
int32 GetSpellCharges(uint8 index=0) const
Definition: Item.h:317
uint32 GetEnchantmentDuration(EnchantmentSlot slot) const
Definition: Item.h:305
int32 GetItemRandomPropertyId() const
Definition: Item.h:295
uint32 GetItemSuffixFactor() const
Definition: Item.h:296
uint32 GetEnchantmentCharges(EnchantmentSlot slot) const
Definition: Item.h:306
void UpdateNextMailTimeAndUnreads()
Definition: PlayerUpdates.cpp:434
PlayerMails const & GetMails() const
Definition: Player.h:1642
Item * GetMItem(ObjectGuid::LowType itemLowGuid)
Definition: Player.h:1657
Definition: Mail.h:168
bool CanOpenMailBox(ObjectGuid guid)
Definition: MailHandler.cpp:37

References _player, CanOpenMailBox(), DAY, Item::GetCount(), ObjectGuid::GetCounter(), Item::GetEnchantmentCharges(), Item::GetEnchantmentDuration(), Item::GetEnchantmentId(), Object::GetEntry(), GameTime::GetGameTime(), Object::GetGUID(), Item::GetItemRandomPropertyId(), Item::GetItemSuffixFactor(), Player::GetMails(), Player::GetMItem(), Item::GetSpellCharges(), Object::GetUInt32Value(), ITEM_FIELD_DURABILITY, ITEM_FIELD_MAXDURABILITY, MAIL_AUCTION, MAIL_CALENDAR, MAIL_CREATURE, MAIL_GAMEOBJECT, MAIL_NORMAL, MAIL_STATE_DELETED, MAX_INBOX_CLIENT_CAPACITY, MAX_INSPECTED_ENCHANTMENT_SLOT, MAX_NETCLIENT_PACKET_SIZE, ByteBuffer::put(), SendPacket(), SMSG_MAIL_LIST_RESULT, Player::UpdateNextMailTimeAndUnreads(), and ByteBuffer::wpos().

Referenced by OpcodeTable::Initialize().

◆ HandleGMResponseResolve()

void WorldSession::HandleGMResponseResolve ( WorldPacket recvPacket)
281{
282 // empty packet
283 if (GmTicket* ticket = sTicketMgr->GetTicketByPlayer(GetPlayer()->GetGUID()))
284 {
285 uint8 getSurvey = 0;
286 if (float(rand_chance()) < sWorld->getFloatConfig(CONFIG_CHANCE_OF_GM_SURVEY))
287 getSurvey = 1;
288
290 data << uint8(getSurvey);
291 SendPacket(&data);
292
295 SendPacket(&data2);
296
297 sTicketMgr->CloseTicket(ticket->GetId(), GetPlayer()->GetGUID());
298 sTicketMgr->SendTicket(this, nullptr);
299 }
300}
double rand_chance()
Definition: Random.cpp:83
#define sTicketMgr
Definition: TicketMgr.h:260
@ GMTICKET_RESPONSE_TICKET_DELETED
Definition: TicketMgr.h:47
@ CONFIG_CHANCE_OF_GM_SURVEY
Definition: IWorld.h:199
@ SMSG_GMRESPONSE_STATUS_UPDATE
Definition: Opcodes.h:1295
@ SMSG_GMTICKET_DELETETICKET
Definition: Opcodes.h:566
Definition: TicketMgr.h:88

References CONFIG_CHANCE_OF_GM_SURVEY, GetPlayer(), GMTICKET_RESPONSE_TICKET_DELETED, rand_chance(), SendPacket(), SMSG_GMRESPONSE_STATUS_UPDATE, SMSG_GMTICKET_DELETETICKET, sTicketMgr, and sWorld.

Referenced by OpcodeTable::Initialize().

◆ HandleGMSurveySubmit()

void WorldSession::HandleGMSurveySubmit ( WorldPacket recvPacket)
198{
199 uint32 nextSurveyID = sTicketMgr->GetNextSurveyID();
200 // just put the survey into the database
201 uint32 mainSurvey; // GMSurveyCurrentSurvey.dbc, column 1 (all 9) ref to GMSurveySurveys.dbc
202 recv_data >> mainSurvey;
203
204 std::unordered_set<uint32> surveyIds;
205 CharacterDatabaseTransaction trans = CharacterDatabase.BeginTransaction();
206
207 // sub_survey1, r1, comment1, sub_survey2, r2, comment2, sub_survey3, r3, comment3, sub_survey4, r4, comment4, sub_survey5, r5, comment5, sub_survey6, r6, comment6, sub_survey7, r7, comment7, sub_survey8, r8, comment8, sub_survey9, r9, comment9, sub_survey10, r10, comment10,
208 for (uint8 i = 0; i < 10; i++)
209 {
210 uint32 subSurveyId; // ref to i'th GMSurveySurveys.dbc field (all fields in that dbc point to fields in GMSurveyQuestions.dbc)
211 recv_data >> subSurveyId;
212 if (!subSurveyId)
213 break;
214
215 uint8 rank; // probably some sort of ref to GMSurveyAnswers.dbc
216 recv_data >> rank;
217 std::string comment; // comment ("Usage: GMSurveyAnswerSubmit(question, rank, comment)")
218 recv_data >> comment;
219
220 if (!ValidateHyperlinksAndMaybeKick(comment))
221 {
222 return;
223 }
224
225 // make sure the same sub survey is not added to DB twice
226 if (!surveyIds.insert(subSurveyId).second)
227 continue;
228
230 stmt->SetData(0, nextSurveyID);
231 stmt->SetData(1, subSurveyId);
232 stmt->SetData(2, rank);
233 stmt->SetData(3, comment);
234 trans->Append(stmt);
235 }
236
237 std::string comment; // just a guess
238 recv_data >> comment;
239
240 if (!ValidateHyperlinksAndMaybeKick(comment))
241 {
242 return;
243 }
244
246 stmt->SetData(0, GetPlayer()->GetGUID().GetCounter());
247 stmt->SetData(1, nextSurveyID);
248 stmt->SetData(2, mainSurvey);
249 stmt->SetData(3, comment);
250
251 trans->Append(stmt);
252
253 CharacterDatabase.CommitTransaction(trans);
254}
@ CHAR_INS_GM_SURVEY
Definition: CharacterDatabase.h:267
@ CHAR_INS_GM_SUBSURVEY
Definition: CharacterDatabase.h:268
bool ValidateHyperlinksAndMaybeKick(std::string_view str)
Definition: WorldSession.cpp:765

References CHAR_INS_GM_SUBSURVEY, CHAR_INS_GM_SURVEY, CharacterDatabase, GetPlayer(), PreparedStatementBase::SetData(), sTicketMgr, and ValidateHyperlinksAndMaybeKick().

Referenced by OpcodeTable::Initialize().

◆ HandleGMTicketCreateOpcode()

void WorldSession::HandleGMTicketCreateOpcode ( WorldPacket recvPacket)
31{
32 // Don't accept tickets if the ticket queue is disabled. (Ticket UI is greyed out but not fully dependable)
34 return;
35
36 if (GetPlayer()->GetLevel() < sWorld->getIntConfig(CONFIG_TICKET_LEVEL_REQ))
37 {
39 return;
40 }
41
43 GmTicket* ticket = sTicketMgr->GetTicketByPlayer(GetPlayer()->GetGUID());
44
45 if (ticket && ticket->IsCompleted())
46 sTicketMgr->CloseTicket(ticket->GetId(), GetPlayer()->GetGUID());
47
48 // Player must not have ticket
49 if (!ticket || ticket->IsClosed())
50 {
51 uint32 mapId;
52 float x, y, z;
53 std::string message;
54 uint32 needResponse;
55 bool needMoreHelp;
56 uint32 count;
57 std::list<uint32> times;
58 uint32 decompressedSize;
59 std::string chatLog;
60
61 recvData >> mapId;
62 recvData >> x >> y >> z;
63 recvData >> message;
64
66 {
67 return;
68 }
69
70 recvData >> needResponse;
71 recvData >> needMoreHelp;
72
73 recvData >> count;
74
75 for (uint32 i = 0; i < count; i++)
76 {
77 uint32 time;
78 recvData >> time;
79 times.push_back(time);
80 }
81
82 recvData >> decompressedSize;
83
84 if (count && decompressedSize && decompressedSize < 0xFFFF)
85 {
86 uint32 pos = recvData.rpos();
87 ByteBuffer dest;
88 dest.resize(decompressedSize);
89
90 uLongf realSize = decompressedSize;
91 if (uncompress(dest.contents(), &realSize, recvData.contents() + pos, recvData.size() - pos) == Z_OK)
92 {
93 dest >> chatLog;
94 }
95 else
96 {
97 LOG_ERROR("network.opcode", "CMSG_GMTICKET_CREATE possibly corrupt. Uncompression failed.");
98 recvData.rfinish();
99 return;
100 }
101
102 recvData.rfinish(); // Will still have compressed data in buffer.
103 }
104
105 if (!chatLog.empty() && !ValidateHyperlinksAndMaybeKick(chatLog))
106 {
107 return;
108 }
109
110 ticket = new GmTicket(GetPlayer());
111 ticket->SetPosition(mapId, x, y, z);
112 ticket->SetMessage(message);
113 ticket->SetGmAction(needResponse, needMoreHelp);
114
115 if (!chatLog.empty())
116 ticket->SetChatLog(times, chatLog);
117
118 sTicketMgr->AddTicket(ticket);
119 sTicketMgr->UpdateLastChange();
120
122
124 }
125
127 data << uint32(response);
128 SendPacket(&data);
129}
@ GMTICKET_QUEUE_STATUS_DISABLED
Definition: TicketMgr.h:30
GMTicketResponse
Definition: TicketMgr.h:41
@ GMTICKET_RESPONSE_CREATE_ERROR
Definition: TicketMgr.h:44
@ GMTICKET_RESPONSE_CREATE_SUCCESS
Definition: TicketMgr.h:43
@ CONFIG_TICKET_LEVEL_REQ
Definition: IWorld.h:296
@ LANG_TICKET_REQ
Definition: Language.h:1155
@ LANG_COMMAND_TICKETNEW
Definition: Language.h:1011
@ SMSG_GMTICKET_CREATE
Definition: Opcodes.h:548
void SendGMText(std::string_view str)
Definition: Chat.cpp:115
bool IsClosed() const
Definition: TicketMgr.h:94
void SetPosition(uint32 mapId, float x, float y, float z)
Definition: TicketMgr.cpp:223
void SetMessage(std::string const &message)
Definition: TicketMgr.cpp:256
void SetGmAction(uint32 needResponse, bool needMoreHelp)
Definition: TicketMgr.cpp:231
bool IsCompleted() const
Definition: TicketMgr.h:95
uint32 GetId() const
Definition: TicketMgr.h:101
void SetChatLog(std::list< uint32 > time, std::string const &log)
Definition: TicketMgr.cpp:242
void resize(std::size_t newsize)
Definition: ByteBuffer.h:447
uint8 * contents()
Definition: ByteBuffer.h:424

References CONFIG_TICKET_LEVEL_REQ, ByteBuffer::contents(), GmTicket::GetId(), GetPlayer(), GMTICKET_QUEUE_STATUS_DISABLED, GMTICKET_RESPONSE_CREATE_ERROR, GMTICKET_RESPONSE_CREATE_SUCCESS, GmTicket::IsClosed(), GmTicket::IsCompleted(), LANG_COMMAND_TICKETNEW, LANG_TICKET_REQ, LOG_ERROR, ByteBuffer::resize(), ByteBuffer::rfinish(), ByteBuffer::rpos(), ChatHandler::SendGMText(), ChatHandler::SendNotification(), SendPacket(), GmTicket::SetChatLog(), GmTicket::SetGmAction(), GmTicket::SetMessage(), GmTicket::SetPosition(), ByteBuffer::size(), SMSG_GMTICKET_CREATE, sTicketMgr, sWorld, and ValidateHyperlinksAndMaybeKick().

Referenced by OpcodeTable::Initialize().

◆ HandleGMTicketDeleteOpcode()

void WorldSession::HandleGMTicketDeleteOpcode ( WorldPacket recvPacket)
159{
160 if (GmTicket* ticket = sTicketMgr->GetTicketByPlayer(GetPlayer()->GetGUID()))
161 {
164 SendPacket(&data);
165
167
168 sTicketMgr->CloseTicket(ticket->GetId(), GetPlayer()->GetGUID());
169 sTicketMgr->SendTicket(this, nullptr);
170 }
171}
@ LANG_COMMAND_TICKETPLAYERABANDON
Definition: Language.h:1013

References GetPlayer(), GMTICKET_RESPONSE_TICKET_DELETED, LANG_COMMAND_TICKETPLAYERABANDON, ChatHandler::SendGMText(), SendPacket(), SMSG_GMTICKET_DELETETICKET, and sTicketMgr.

Referenced by OpcodeTable::Initialize().

◆ HandleGMTicketGetTicketOpcode()

void WorldSession::HandleGMTicketGetTicketOpcode ( WorldPacket recvPacket)
174{
176
177 if (GmTicket* ticket = sTicketMgr->GetTicketByPlayer(GetPlayer()->GetGUID()))
178 {
179 if (ticket->IsCompleted())
180 ticket->SendResponse(this);
181 else
182 sTicketMgr->SendTicket(this, ticket);
183 }
184 else
185 sTicketMgr->SendTicket(this, nullptr);
186}
void SendQueryTimeResponse()
Definition: QueryHandler.cpp:83

References GetPlayer(), SendQueryTimeResponse(), and sTicketMgr.

Referenced by OpcodeTable::Initialize().

◆ HandleGMTicketSystemStatusOpcode()

void WorldSession::HandleGMTicketSystemStatusOpcode ( WorldPacket recvPacket)
189{
190 // Note: This only disables the ticket UI at client side and is not fully reliable
191 // are we sure this is a uint32? Should ask Zor
194 SendPacket(&data);
195}
@ GMTICKET_QUEUE_STATUS_ENABLED
Definition: TicketMgr.h:31
@ SMSG_GMTICKET_SYSTEMSTATUS
Definition: Opcodes.h:569

References GMTICKET_QUEUE_STATUS_DISABLED, GMTICKET_QUEUE_STATUS_ENABLED, SendPacket(), SMSG_GMTICKET_SYSTEMSTATUS, and sTicketMgr.

Referenced by OpcodeTable::Initialize().

◆ HandleGMTicketUpdateOpcode()

void WorldSession::HandleGMTicketUpdateOpcode ( WorldPacket recvPacket)
132{
133 std::string message;
134 recv_data >> message;
135
136 if (!ValidateHyperlinksAndMaybeKick(message))
137 {
138 return;
139 }
140
142 if (GmTicket* ticket = sTicketMgr->GetTicketByPlayer(GetPlayer()->GetGUID()))
143 {
145 ticket->SetMessage(message);
146 ticket->SaveToDB(trans);
147
148 ChatHandler(nullptr).SendGMText(LANG_COMMAND_TICKETUPDATED, GetPlayer()->GetName(), ticket->GetId());
149
151 }
152
154 data << uint32(response);
155 SendPacket(&data);
156}
@ GMTICKET_RESPONSE_UPDATE_SUCCESS
Definition: TicketMgr.h:45
@ GMTICKET_RESPONSE_UPDATE_ERROR
Definition: TicketMgr.h:46
@ LANG_COMMAND_TICKETUPDATED
Definition: Language.h:1012
@ SMSG_GMTICKET_UPDATETEXT
Definition: Opcodes.h:550

References GetPlayer(), GMTICKET_RESPONSE_UPDATE_ERROR, GMTICKET_RESPONSE_UPDATE_SUCCESS, LANG_COMMAND_TICKETUPDATED, ChatHandler::SendGMText(), SendPacket(), SMSG_GMTICKET_UPDATETEXT, sTicketMgr, and ValidateHyperlinksAndMaybeKick().

Referenced by OpcodeTable::Initialize().

◆ HandleGossipHelloOpcode()

void WorldSession::HandleGossipHelloOpcode ( WorldPacket recvPacket)
274{
275 ObjectGuid guid;
276 recvData >> guid;
277
279 if (!unit)
280 {
281 LOG_DEBUG("network", "WORLD: HandleGossipHelloOpcode - Unit ({}) not found or you can not interact with him.", guid.ToString());
282 return;
283 }
284
285 // xinef: check if we have ANY npc flags
286 if (unit->GetNpcFlags() == UNIT_NPC_FLAG_NONE)
287 return;
288
289 // set faction visible if needed
290 if (FactionTemplateEntry const* factionTemplateEntry = sFactionTemplateStore.LookupEntry(unit->GetFaction()))
291 _player->GetReputationMgr().SetVisible(factionTemplateEntry);
292
294 // remove fake death
295 //if (GetPlayer()->HasUnitState(UNIT_STATE_DIED))
296 // GetPlayer()->RemoveAurasByType(SPELL_AURA_FEIGN_DEATH);
297
298 // Stop the npc if moving
300 unit->PauseMovement(pause);
301 unit->SetHomePosition(unit->GetPosition());
302
303 // If spiritguide, no need for gossip menu, just put player into resurrect queue
304 if (unit->IsSpiritGuide())
305 {
307 if (bg)
308 {
310 sBattlegroundMgr->SendAreaSpiritHealerQueryOpcode(_player, bg, unit->GetGUID());
311 return;
312 }
313 }
314
315 if (!sScriptMgr->OnGossipHello(_player, unit))
316 {
317 // _player->TalkedToCreature(unit->GetEntry(), unit->GetGUID());
320 }
321 unit->AI()->sGossipHello(_player);
322}
DBCStorage< FactionTemplateEntry > sFactionTemplateStore(FactionTemplateEntryfmt)
@ UNIT_NPC_FLAG_NONE
Definition: UnitDefines.h:293
@ AURA_INTERRUPT_FLAG_TALK
Definition: SpellDefines.h:53
virtual void sGossipHello(Player *)
Definition: UnitAI.h:413
CreatureTemplate const * GetCreatureTemplate() const
Definition: Creature.h:208
CreatureAI * AI() const
Definition: Creature.h:143
uint32 GossipMenuId
Definition: CreatureData.h:195
void SendPreparedGossip(WorldObject *source)
Definition: PlayerGossip.cpp:209
void PrepareGossipMenu(WorldObject *source, uint32 menuId=0, bool showQuests=false)
Definition: PlayerGossip.cpp:32
ReputationMgr & GetReputationMgr()
Definition: Player.h:2107
NPCFlags GetNpcFlags() const
Definition: Unit.h:693
void RemoveAurasWithInterruptFlags(uint32 flag, uint32 except=0, bool isAutoshot=false)
Definition: Unit.cpp:5159
bool IsSpiritGuide() const
Definition: Unit.h:726
void SetVisible(FactionTemplateEntry const *factionTemplateEntry)
Definition: ReputationMgr.cpp:458
Definition: DBCStructure.h:938

References _player, Battleground::AddPlayerToResurrectQueue(), Creature::AI(), AURA_INTERRUPT_FLAG_TALK, Player::GetBattleground(), Creature::GetCreatureTemplate(), Unit::GetFaction(), Object::GetGUID(), CreatureMovementData::GetInteractionPauseTimer(), Creature::GetMovementTemplate(), Unit::GetNpcFlags(), Player::GetNPCIfCanInteractWith(), GetPlayer(), Position::GetPosition(), Player::GetReputationMgr(), CreatureTemplate::GossipMenuId, Unit::IsSpiritGuide(), LOG_DEBUG, Unit::PauseMovement(), Player::PrepareGossipMenu(), Unit::RemoveAurasWithInterruptFlags(), sBattlegroundMgr, Player::SendPreparedGossip(), Creature::SetHomePosition(), ReputationMgr::SetVisible(), sFactionTemplateStore, UnitAI::sGossipHello(), sScriptMgr, ObjectGuid::ToString(), and UNIT_NPC_FLAG_NONE.

Referenced by OpcodeTable::Initialize().

◆ HandleGossipSelectOptionOpcode()

void WorldSession::HandleGossipSelectOptionOpcode ( WorldPacket recvPacket)
87{
88 LOG_DEBUG("network", "WORLD: CMSG_GOSSIP_SELECT_OPTION");
89
90 uint32 gossipListId;
91 uint32 menuId;
92 ObjectGuid guid;
93 std::string code = "";
94
95 recv_data >> guid >> menuId >> gossipListId;
96
98 recv_data >> code;
99
100 // Prevent cheating on C++ scripted menus
102 {
103 return;
104 }
105
106 Creature* unit = nullptr;
107 GameObject* go = nullptr;
108 Item* item = nullptr;
109 if (guid.IsCreatureOrVehicle())
110 {
112 if (!unit)
113 {
114 LOG_DEBUG("network", "WORLD: HandleGossipSelectOptionOpcode - Unit ({}) not found or you can't interact with him.", guid.ToString());
115 return;
116 }
117 }
118 else if (guid.IsGameObject())
119 {
120 go = _player->GetMap()->GetGameObject(guid);
121 if (!go)
122 {
123 LOG_DEBUG("network", "WORLD: HandleGossipSelectOptionOpcode - GameObject ({}) not found.", guid.ToString());
124 return;
125 }
126 }
127 else if (guid.IsItem())
128 {
129 item = _player->GetItemByGuid(guid);
130 if (!item || _player->IsBankPos(item->GetPos()))
131 {
132 //LOG_DEBUG("network", "WORLD: HandleGossipSelectOptionOpcode - {} not found.", guid.ToString());
133 return;
134 }
135 }
136 else if (guid.IsPlayer())
137 {
138 if (guid != _player->GetGUID() || menuId != _player->PlayerTalkClass->GetGossipMenu().GetMenuId())
139 {
140 //LOG_DEBUG("network", "WORLD: HandleGossipSelectOptionOpcode - {} not found.", guid.ToString());
141 return;
142 }
143 }
144 else
145 {
146 LOG_DEBUG("network", "WORLD: HandleGossipSelectOptionOpcode - unsupported GUID type for {}.", guid.ToString());
147 return;
148 }
149
150 // remove fake death
151 if (GetPlayer()->HasUnitState(UNIT_STATE_DIED))
153
154 if ((unit && unit->GetScriptId() != unit->LastUsedScriptID) || (go && go->GetScriptId() != go->LastUsedScriptID))
155 {
156 LOG_DEBUG("network", "WORLD: HandleGossipSelectOptionOpcode - Script reloaded while in use, ignoring and set new scipt id");
157 if (unit)
158 unit->LastUsedScriptID = unit->GetScriptId();
159 if (go)
160 go->LastUsedScriptID = go->GetScriptId();
162 return;
163 }
164 if (!code.empty())
165 {
166 if (unit)
167 {
168 unit->AI()->sGossipSelectCode(_player, menuId, gossipListId, code.c_str());
169 if (!sScriptMgr->OnGossipSelectCode(_player, unit, _player->PlayerTalkClass->GetGossipOptionSender(gossipListId), _player->PlayerTalkClass->GetGossipOptionAction(gossipListId), code.c_str()))
170 _player->OnGossipSelect(unit, gossipListId, menuId);
171 }
172 else if (go)
173 {
174 go->AI()->GossipSelectCode(_player, menuId, gossipListId, code.c_str());
175 sScriptMgr->OnGossipSelectCode(_player, go, _player->PlayerTalkClass->GetGossipOptionSender(gossipListId), _player->PlayerTalkClass->GetGossipOptionAction(gossipListId), code.c_str());
176 }
177 else if (item)
178 {
179 sScriptMgr->OnGossipSelectCode(_player, item, _player->PlayerTalkClass->GetGossipOptionSender(gossipListId), _player->PlayerTalkClass->GetGossipOptionAction(gossipListId), code.c_str());
180 }
181 else
182 {
183 sScriptMgr->OnGossipSelectCode(_player, menuId, _player->PlayerTalkClass->GetGossipOptionSender(gossipListId), _player->PlayerTalkClass->GetGossipOptionAction(gossipListId), code.c_str());
184 }
185 }
186 else
187 {
188 if (unit)
189 {
190 unit->AI()->sGossipSelect(_player, menuId, gossipListId);
191 if (!sScriptMgr->OnGossipSelect(_player, unit, _player->PlayerTalkClass->GetGossipOptionSender(gossipListId), _player->PlayerTalkClass->GetGossipOptionAction(gossipListId)))
192 _player->OnGossipSelect(unit, gossipListId, menuId);
193 }
194 else if (go)
195 {
196 go->AI()->GossipSelect(_player, menuId, gossipListId);
197 if (!sScriptMgr->OnGossipSelect(_player, go, _player->PlayerTalkClass->GetGossipOptionSender(gossipListId), _player->PlayerTalkClass->GetGossipOptionAction(gossipListId)))
198 _player->OnGossipSelect(go, gossipListId, menuId);
199 }
200 else if (item)
201 {
202 sScriptMgr->OnGossipSelect(_player, item, _player->PlayerTalkClass->GetGossipOptionSender(gossipListId), _player->PlayerTalkClass->GetGossipOptionAction(gossipListId));
203 }
204 else
205 {
206 sScriptMgr->OnGossipSelect(_player, menuId, _player->PlayerTalkClass->GetGossipOptionSender(gossipListId), _player->PlayerTalkClass->GetGossipOptionAction(gossipListId));
207 }
208 }
209}
virtual bool GossipSelectCode(Player *, uint32, uint32, char const *)
Definition: GameObjectAI.h:56
virtual bool GossipSelect(Player *, uint32, uint32)
Definition: GameObjectAI.h:55
virtual void sGossipSelectCode(Player *, uint32, uint32, char const *)
Definition: UnitAI.h:415
virtual void sGossipSelect(Player *, uint32, uint32)
Definition: UnitAI.h:414
uint32 GetScriptId() const
Definition: Creature.cpp:3042
uint32 GetMenuId() const
Definition: GossipDef.h:171
ObjectGuid GetSenderGUID() const
Definition: GossipDef.h:217
void SendCloseGossip()
Definition: GossipDef.cpp:239
bool IsGossipOptionCoded(uint32 selection) const
Definition: GossipDef.h:271
uint32 GetGossipOptionSender(uint32 selection) const
Definition: GossipDef.h:269
GossipMenu & GetGossipMenu()
Definition: GossipDef.h:263
uint32 GetGossipOptionAction(uint32 selection) const
Definition: GossipDef.h:270
virtual uint32 GetScriptId() const
Definition: GameObject.cpp:2197
uint32 LastUsedScriptID
Definition: Object.h:596
bool IsCreatureOrVehicle() const
Definition: ObjectGuid.h:166
void OnGossipSelect(WorldObject *source, uint32 gossipListId, uint32 menuId)
Definition: PlayerGossip.cpp:244
PlayerMenu * PlayerTalkClass
Definition: Player.h:2221

References _player, Creature::AI(), GameObject::AI(), Map::GetGameObject(), PlayerMenu::GetGossipMenu(), PlayerMenu::GetGossipOptionAction(), PlayerMenu::GetGossipOptionSender(), Object::GetGUID(), Player::GetItemByGuid(), WorldObject::GetMap(), GossipMenu::GetMenuId(), Player::GetNPCIfCanInteractWith(), GetPlayer(), Item::GetPos(), Creature::GetScriptId(), GameObject::GetScriptId(), GossipMenu::GetSenderGUID(), GameObjectAI::GossipSelect(), GameObjectAI::GossipSelectCode(), Player::IsBankPos(), ObjectGuid::IsCreatureOrVehicle(), ObjectGuid::IsGameObject(), PlayerMenu::IsGossipOptionCoded(), ObjectGuid::IsItem(), ObjectGuid::IsPlayer(), WorldObject::LastUsedScriptID, LOG_DEBUG, Player::OnGossipSelect(), Player::PlayerTalkClass, Unit::RemoveAurasByType(), PlayerMenu::SendCloseGossip(), UnitAI::sGossipSelect(), UnitAI::sGossipSelectCode(), SPELL_AURA_FEIGN_DEATH, sScriptMgr, ObjectGuid::ToString(), UNIT_NPC_FLAG_NONE, and UNIT_STATE_DIED.

Referenced by OpcodeTable::Initialize().

◆ HandleGrantLevel()

void WorldSession::HandleGrantLevel ( WorldPacket recvData)
24{
25 LOG_DEBUG("network", "WORLD: CMSG_GRANT_LEVEL");
26
27 ObjectGuid guid;
28 recvData >> guid.ReadAsPacked();
29
31
32 // check cheating
34 uint8 error = 0;
35 if (!target)
37 else if (levels == 0)
39 else if (GetRecruiterId() != target->GetSession()->GetAccountId())
41 else if (target->GetTeamId() != _player->GetTeamId())
43 else if (target->GetLevel() >= _player->GetLevel())
45 else if (target->GetLevel() >= sWorld->getIntConfig(CONFIG_MAX_RECRUIT_A_FRIEND_BONUS_PLAYER_LEVEL))
47 else if (target->GetGroup() != _player->GetGroup())
49
50 if (error)
51 {
53 data << uint32(error);
55 data << target->GetName();
56
57 SendPacket(&data);
58 return;
59 }
60
62 data2 << _player->GetPackGUID();
63 target->GetSession()->SendPacket(&data2);
64}
@ CONFIG_MAX_RECRUIT_A_FRIEND_BONUS_PLAYER_LEVEL
Definition: IWorld.h:246
@ ERR_REFER_A_FRIEND_TARGET_TOO_HIGH
Definition: Player.h:968
@ ERR_REFER_A_FRIEND_DIFFERENT_FACTION
Definition: Player.h:971
@ ERR_REFER_A_FRIEND_NO_TARGET
Definition: Player.h:974
@ ERR_REFER_A_FRIEND_INSUFFICIENT_GRANTABLE_LEVELS
Definition: Player.h:969
@ ERR_REFER_A_FRIEND_NOT_REFERRED_BY
Definition: Player.h:967
@ ERR_REFER_A_FRIEND_NOT_IN_GROUP
Definition: Player.h:975
@ ERR_REFER_A_FRIEND_GRANT_LEVEL_MAX_I
Definition: Player.h:973
@ SMSG_REFER_A_FRIEND_FAILURE
Definition: Opcodes.h:1087
@ SMSG_PROPOSE_LEVEL_GRANT
Definition: Opcodes.h:1085

References _player, CONFIG_MAX_RECRUIT_A_FRIEND_BONUS_PLAYER_LEVEL, ERR_REFER_A_FRIEND_DIFFERENT_FACTION, ERR_REFER_A_FRIEND_GRANT_LEVEL_MAX_I, ERR_REFER_A_FRIEND_INSUFFICIENT_GRANTABLE_LEVELS, ERR_REFER_A_FRIEND_NO_TARGET, ERR_REFER_A_FRIEND_NOT_IN_GROUP, ERR_REFER_A_FRIEND_NOT_REFERRED_BY, ERR_REFER_A_FRIEND_TARGET_TOO_HIGH, GetAccountId(), Player::GetGrantableLevels(), Player::GetGroup(), Unit::GetLevel(), WorldObject::GetName(), Object::GetPackGUID(), ObjectAccessor::GetPlayer(), GetRecruiterId(), Player::GetSession(), Player::GetTeamId(), LOG_DEBUG, ObjectGuid::ReadAsPacked(), SendPacket(), SMSG_PROPOSE_LEVEL_GRANT, SMSG_REFER_A_FRIEND_FAILURE, and sWorld.

Referenced by OpcodeTable::Initialize().

◆ HandleGroupAcceptOpcode()

void WorldSession::HandleGroupAcceptOpcode ( WorldPacket recvPacket)
217{
218 recvData.read_skip<uint32>();
219 Group* group = GetPlayer()->GetGroupInvite();
220
221 if (!group)
222 return;
223
224 // Remove player from invitees in any case
225 group->RemoveInvite(GetPlayer());
226
227 if (GetPlayer()->IsSpectator())
228 {
230 return;
231 }
232
233 if (!sScriptMgr->CanGroupAccept(GetPlayer(), group))
234 return;
235
236 if (group->GetLeaderGUID() == GetPlayer()->GetGUID())
237 {
238 LOG_ERROR("network.opcode", "HandleGroupAcceptOpcode: player {} ({}) tried to accept an invite to his own group",
239 GetPlayer()->GetName(), GetPlayer()->GetGUID().ToString());
240 return;
241 }
242
243 // Group is full
244 if (group->IsFull())
245 {
247 return;
248 }
249
250 Player* leader = ObjectAccessor::FindConnectedPlayer(group->GetLeaderGUID());
251
252 // Forming a new group, create it
253 if (!group->IsCreated())
254 {
255 // This can happen if the leader is zoning. To be removed once delayed actions for zoning are implemented
256 if (!leader || leader->IsSpectator())
257 {
258 group->RemoveAllInvites();
259 return;
260 }
261
262 // If we're about to create a group there really should be a leader present
263 ASSERT(leader);
264 group->RemoveInvite(leader);
265 group->Create(leader);
266 sGroupMgr->AddGroup(group);
267 }
268
269 // Everything is fine, do it, PLAYER'S GROUP IS SET IN ADDMEMBER!!!
270 if (!group->AddMember(GetPlayer()))
271 return;
272
273 group->BroadcastGroupUpdate();
274}
#define sGroupMgr
Definition: GroupMgr.h:51
@ ERR_INVITE_RESTRICTED
Definition: SharedDefines.h:3716
@ ERR_GROUP_FULL
Definition: SharedDefines.h:3709
@ PARTY_OP_INVITE
Definition: WorldSession.h:191
bool IsSpectator() const
Definition: Player.h:2558
Group * GetGroupInvite()
Definition: Player.h:2448
void RemoveInvite(Player *player)
Definition: Group.cpp:353
void SendPartyResult(PartyOperation operation, std::string const &member, PartyResult res, uint32 val=0)
Definition: GroupHandler.cpp:52

References ASSERT, ERR_GROUP_FULL, ERR_INVITE_RESTRICTED, ObjectAccessor::FindConnectedPlayer(), Player::GetGroupInvite(), GetPlayer(), Player::IsSpectator(), LOG_ERROR, PARTY_OP_INVITE, ByteBuffer::read_skip(), Group::RemoveInvite(), SendPartyResult(), sGroupMgr, and sScriptMgr.

Referenced by OpcodeTable::Initialize().

◆ HandleGroupAssistantLeaderOpcode()

void WorldSession::HandleGroupAssistantLeaderOpcode ( WorldPacket recvData)
660{
661 Group* group = GetPlayer()->GetGroup();
662 if (!group)
663 return;
664
665 if (!group->IsLeader(GetPlayer()->GetGUID()))
666 return;
667
668 ObjectGuid guid;
669 bool apply;
670 recvData >> guid;
671 recvData >> apply;
672
673 group->SetGroupMemberFlag(guid, apply, MEMBER_FLAG_ASSISTANT);
674
675 group->SendUpdate();
676}
@ MEMBER_FLAG_ASSISTANT
Definition: Group.h:73
bool IsLeader(ObjectGuid guid) const
Definition: Group.cpp:2341
void SendUpdate()
Definition: Group.cpp:1665
void SetGroupMemberFlag(ObjectGuid guid, bool apply, GroupMemberFlags flag)
Definition: Group.cpp:2402

References Player::GetGroup(), GetPlayer(), Group::IsLeader(), MEMBER_FLAG_ASSISTANT, Group::SendUpdate(), and Group::SetGroupMemberFlag().

Referenced by OpcodeTable::Initialize().

◆ HandleGroupChangeSubGroupOpcode()

void WorldSession::HandleGroupChangeSubGroupOpcode ( WorldPacket recvData)
623{
624 // we will get correct pointer for group here, so we don't have to check if group is BG raid
625 Group* group = GetPlayer()->GetGroup();
626 if (!group)
627 return;
628
629 std::string name;
630 uint8 groupNr;
631 recvData >> name;
632 recvData >> groupNr;
633
634 if (groupNr >= MAX_RAID_SUBGROUPS)
635 return;
636
637 ObjectGuid senderGuid = GetPlayer()->GetGUID();
638 if (!group->IsLeader(senderGuid) && !group->IsAssistant(senderGuid))
639 return;
640
641 if (!group->HasFreeSlotSubGroup(groupNr))
642 return;
643
644 Player* movedPlayer = ObjectAccessor::FindPlayerByName(name, false);
645 ObjectGuid guid;
646 if (movedPlayer)
647 {
648 guid = movedPlayer->GetGUID();
649 }
650 else
651 {
652 CharacterDatabase.EscapeString(name);
653 guid = sCharacterCache->GetCharacterGuidByName(name);
654 }
655
656 group->ChangeMembersGroup(guid, groupNr);
657}
#define MAX_RAID_SUBGROUPS
Definition: Group.h:45
void ChangeMembersGroup(ObjectGuid guid, uint8 group)
Definition: Group.cpp:1808
bool IsAssistant(ObjectGuid guid) const
Definition: Group.cpp:2355
bool HasFreeSlotSubGroup(uint8 subgroup) const
Definition: Group.cpp:2379

References Group::ChangeMembersGroup(), CharacterDatabase, ObjectAccessor::FindPlayerByName(), Player::GetGroup(), Object::GetGUID(), GetPlayer(), Group::HasFreeSlotSubGroup(), Group::IsAssistant(), Group::IsLeader(), MAX_RAID_SUBGROUPS, and sCharacterCache.

Referenced by OpcodeTable::Initialize().

◆ HandleGroupDeclineOpcode()

void WorldSession::HandleGroupDeclineOpcode ( WorldPacket recvPacket)
277{
278 Group* group = GetPlayer()->GetGroupInvite();
279 if (!group)
280 return;
281
282 // Remember leader if online (group pointer will be invalid if group gets disbanded)
284
285 // uninvite, group can be deleted
287
288 if (!leader)
289 return;
290
291 // report
292 WorldPacket data(SMSG_GROUP_DECLINE, GetPlayer()->GetName().length());
293 data << GetPlayer()->GetName();
294 leader->GetSession()->SendPacket(&data);
295}
@ SMSG_GROUP_DECLINE
Definition: Opcodes.h:146
void UninviteFromGroup()
Definition: Player.cpp:2316

References ObjectAccessor::FindConnectedPlayer(), Player::GetGroupInvite(), Group::GetLeaderGUID(), WorldObject::GetName(), GetPlayer(), Player::GetSession(), SendPacket(), SMSG_GROUP_DECLINE, and Player::UninviteFromGroup().

Referenced by OpcodeTable::Initialize().

◆ HandleGroupDisbandOpcode()

void WorldSession::HandleGroupDisbandOpcode ( WorldPacket recvPacket)

error handling

435{
436 Group* grp = GetPlayer()->GetGroup();
437 Group* grpInvite = GetPlayer()->GetGroupInvite();
438 if (!grp && !grpInvite)
439 return;
440
441 if (_player->InBattleground())
442 {
444 return;
445 }
446
448 /********************/
449
450 // everything's fine, do it
451 if (grp)
452 {
455 }
456 else if (grpInvite && grpInvite->GetLeaderGUID() == GetPlayer()->GetGUID())
457 { // pending group creation being cancelled
459 grpInvite->Disband();
460 }
461}
@ GROUP_REMOVEMETHOD_LEAVE
Definition: SharedDefines.h:3589
@ ERR_PARTY_RESULT_OK
Definition: SharedDefines.h:3705
@ PARTY_OP_LEAVE
Definition: WorldSession.h:193
static void RemoveFromGroup(Group *group, ObjectGuid guid, RemoveMethod method=GROUP_REMOVEMETHOD_DEFAULT, ObjectGuid kicker=ObjectGuid::Empty, const char *reason=nullptr)
Definition: Player.cpp:2343
void Disband(bool hideDestroy=false)
Definition: Group.cpp:755

References _player, Group::Disband(), ERR_INVITE_RESTRICTED, ERR_PARTY_RESULT_OK, Player::GetGroup(), Player::GetGroupInvite(), Group::GetLeaderGUID(), GetPlayer(), GROUP_REMOVEMETHOD_LEAVE, Player::InBattleground(), PARTY_OP_INVITE, PARTY_OP_LEAVE, Player::RemoveFromGroup(), and SendPartyResult().

Referenced by OpcodeTable::Initialize().

◆ HandleGroupInviteOpcode()

void WorldSession::HandleGroupInviteOpcode ( WorldPacket recvPacket)
64{
65 std::string membername;
66 recvData >> membername;
67 recvData.read_skip<uint32>();
68
69 // attempt add selected player
70
71 // cheating
72 if (!normalizePlayerName(membername))
73 {
75 return;
76 }
77
78 Player* invitingPlayer = GetPlayer();
79 Player* invitedPlayer = ObjectAccessor::FindPlayerByName(membername, false);
80
81 // no player or cheat self-invite
82 if (!invitedPlayer || invitedPlayer == invitingPlayer)
83 {
85 return;
86 }
87
88 if (!sScriptMgr->CanGroupInvite(invitingPlayer, membername))
89 return;
90
91 if (invitingPlayer->IsSpectator() || invitedPlayer->IsSpectator())
92 {
94 return;
95 }
96
97 // restrict invite to GMs
98 if (!sWorld->getBoolConfig(CONFIG_ALLOW_GM_GROUP) && !invitingPlayer->IsGameMaster() && invitedPlayer->IsGameMaster())
99 {
101 return;
102 }
103
104 // can't group with
105 if (!invitingPlayer->IsGameMaster() && !sWorld->getBoolConfig(CONFIG_ALLOW_TWO_SIDE_INTERACTION_GROUP) && invitingPlayer->GetTeamId() != invitedPlayer->GetTeamId())
106 {
108 return;
109 }
110 if (invitingPlayer->GetInstanceId() != 0 && invitedPlayer->GetInstanceId() != 0 && invitingPlayer->GetInstanceId() != invitedPlayer->GetInstanceId() && invitingPlayer->GetMapId() == invitedPlayer->GetMapId())
111 {
113 return;
114 }
115
116 if (invitedPlayer->GetSocial()->HasIgnore(invitingPlayer->GetGUID()))
117 {
119 return;
120 }
121
122 if (!invitedPlayer->GetSocial()->HasFriend(invitingPlayer->GetGUID()) && invitingPlayer->GetLevel() < sWorld->getIntConfig(CONFIG_PARTY_LEVEL_REQ))
123 {
125 return;
126 }
127
128 Group* group = invitingPlayer->GetGroup();
129 if (group && group->isBGGroup())
130 group = invitingPlayer->GetOriginalGroup();
131 if (!group)
132 group = invitingPlayer->GetGroupInvite();
133
134 Group* group2 = invitedPlayer->GetGroup();
135 if (group2 && group2->isBGGroup())
136 group2 = invitedPlayer->GetOriginalGroup();
137 // player already in another group or invited
138 if (group2 || invitedPlayer->GetGroupInvite())
139 {
141
142 if (group2)
143 {
144 // tell the player that they were invited but it failed as they were already in a group
145 WorldPacket data(SMSG_GROUP_INVITE, 25); // guess size
146 data << uint8(0); // invited/already in group flag
147 data << invitingPlayer->GetName(); // max len 48
148 data << uint32(0); // unk
149 data << uint8(0); // count
150 data << uint32(0); // unk
151 invitedPlayer->GetSession()->SendPacket(&data);
152 }
153
154 return;
155 }
156
157 if (group)
158 {
159 // not have permissions for invite
160 if (!group->IsLeader(invitingPlayer->GetGUID()) && !group->IsAssistant(invitingPlayer->GetGUID()))
161 {
163 return;
164 }
165 // not have place
166 if (group->IsFull())
167 {
169 return;
170 }
171 }
172
173 // xinef: if player has no group, check group invite
174 if (!group && invitingPlayer->GetGroupInvite() && invitingPlayer->GetGroupInvite()->GetLeaderGUID() == invitingPlayer->GetGUID())
175 group = invitingPlayer->GetGroupInvite();
176
177 // ok, but group not exist, start a new group
178 // but don't create and save the group to the DB until
179 // at least one person joins
180 if (!group)
181 {
182 group = new Group();
183 // new group: if can't add then delete
184 if (!group->AddLeaderInvite(invitingPlayer))
185 {
186 delete group;
187 return;
188 }
189 if (!group->AddInvite(invitedPlayer))
190 {
191 delete group;
192 return;
193 }
194 }
195 else
196 {
197 // already existed group: if can't add then just leave
198 if (!group->AddInvite(invitedPlayer))
199 {
200 return;
201 }
202 }
203
204 // ok, we do it
205 WorldPacket data(SMSG_GROUP_INVITE, 10); // guess size
206 data << uint8(1); // invited/already in group flag
207 data << invitingPlayer->GetName(); // max len 48
208 data << uint32(0); // unk
209 data << uint8(0); // count
210 data << uint32(0); // unk
211 invitedPlayer->GetSession()->SendPacket(&data);
212
214}
@ CONFIG_PARTY_LEVEL_REQ
Definition: IWorld.h:293
@ CONFIG_ALLOW_GM_GROUP
Definition: IWorld.h:88
@ CONFIG_ALLOW_TWO_SIDE_INTERACTION_GROUP
Definition: IWorld.h:75
@ ERR_ALREADY_IN_GROUP_S
Definition: SharedDefines.h:3710
@ ERR_TARGET_NOT_IN_INSTANCE_S
Definition: SharedDefines.h:3708
@ ERR_IGNORING_YOU_S
Definition: SharedDefines.h:3714
@ ERR_NOT_LEADER
Definition: SharedDefines.h:3712
@ ERR_PLAYER_WRONG_FACTION
Definition: SharedDefines.h:3713
@ ERR_BAD_PLAYER_NAME_S
Definition: SharedDefines.h:3706
@ SMSG_GROUP_INVITE
Definition: Opcodes.h:141
uint32 GetInstanceId() const
Definition: Object.h:443
Group * GetOriginalGroup()
Definition: Player.h:2465
bool HasFriend(ObjectGuid friend_guid) const
Definition: SocialMgr.cpp:188
bool AddLeaderInvite(Player *player)
Definition: Group.cpp:343
bool isBGGroup() const
Definition: Group.cpp:2276
bool AddInvite(Player *player)
Definition: Group.cpp:322
bool IsFull() const
Definition: Group.cpp:2260

References Group::AddInvite(), Group::AddLeaderInvite(), CONFIG_ALLOW_GM_GROUP, CONFIG_ALLOW_TWO_SIDE_INTERACTION_GROUP, CONFIG_PARTY_LEVEL_REQ, ERR_ALREADY_IN_GROUP_S, ERR_BAD_PLAYER_NAME_S, ERR_GROUP_FULL, ERR_IGNORING_YOU_S, ERR_INVITE_RESTRICTED, ERR_NOT_LEADER, ERR_PARTY_RESULT_OK, ERR_PLAYER_WRONG_FACTION, ERR_TARGET_NOT_IN_INSTANCE_S, ObjectAccessor::FindPlayerByName(), Player::GetGroup(), Player::GetGroupInvite(), Object::GetGUID(), WorldObject::GetInstanceId(), Group::GetLeaderGUID(), Unit::GetLevel(), WorldLocation::GetMapId(), WorldObject::GetName(), Player::GetOriginalGroup(), GetPlayer(), Player::GetSession(), Player::GetSocial(), Player::GetTeamId(), PlayerSocial::HasFriend(), PlayerSocial::HasIgnore(), Group::IsAssistant(), Group::isBGGroup(), Group::IsFull(), Player::IsGameMaster(), Group::IsLeader(), Player::IsSpectator(), normalizePlayerName(), PARTY_OP_INVITE, ByteBuffer::read_skip(), SendPacket(), SendPartyResult(), SMSG_GROUP_INVITE, sScriptMgr, and sWorld.

Referenced by OpcodeTable::Initialize().

◆ HandleGroupRaidConvertOpcode()

void WorldSession::HandleGroupRaidConvertOpcode ( WorldPacket recvData)

error handling

598{
599 Group* group = GetPlayer()->GetGroup();
600 if (!group)
601 return;
602
603 if (_player->InBattleground())
604 return;
605
607 if (group->CheckLevelForRaid())
608 {
610 return;
611 }
612
613 if (!group->IsLeader(GetPlayer()->GetGUID()) || group->GetMembersCount() < 2 || group->isLFGGroup()) // pussywizard: not allowed for lfg groups, it is either raid from the beginning or not!
614 return;
615 /********************/
616
617 // everything's fine, do it (is it 0 (PARTY_OP_INVITE) correct code)
619 group->ConvertToRaid();
620}
@ ERR_RAID_DISALLOWED_BY_LEVEL
Definition: SharedDefines.h:3728
bool CheckLevelForRaid()
Definition: Group.cpp:284
bool isLFGGroup(bool restricted=false) const
Definition: Group.cpp:2265
void ConvertToRaid()
Definition: Group.cpp:294

References _player, Group::CheckLevelForRaid(), Group::ConvertToRaid(), ERR_PARTY_RESULT_OK, ERR_RAID_DISALLOWED_BY_LEVEL, Player::GetGroup(), Group::GetMembersCount(), GetPlayer(), Player::InBattleground(), Group::IsLeader(), Group::isLFGGroup(), PARTY_OP_INVITE, and SendPartyResult().

Referenced by OpcodeTable::Initialize().

◆ HandleGroupSetLeaderOpcode()

void WorldSession::HandleGroupSetLeaderOpcode ( WorldPacket recvPacket)
416{
417 ObjectGuid guid;
418 recvData >> guid;
419
421 Group* group = GetPlayer()->GetGroup();
422
423 if (!group || !player)
424 return;
425
426 if (!group->IsLeader(GetPlayer()->GetGUID()) || player->GetGroup() != group || guid == GetPlayer()->GetGUID())
427 return;
428
429 // Everything's fine, accepted.
430 group->ChangeLeader(guid);
431 group->SendUpdate();
432}
void ChangeLeader(ObjectGuid guid)
Definition: Group.cpp:714

References Group::ChangeLeader(), ObjectAccessor::FindConnectedPlayer(), Player::GetGroup(), GetPlayer(), Group::IsLeader(), and Group::SendUpdate().

Referenced by OpcodeTable::Initialize().

◆ HandleGroupSwapSubGroupOpcode()

void WorldSession::HandleGroupSwapSubGroupOpcode ( WorldPacket recvData)
1105{
1106 std::string playerName1, playerName2;
1107
1108 // first = moved from, second = moved to
1109 recv_data >> playerName1;
1110 recv_data >> playerName2;
1111
1112 if (!normalizePlayerName(playerName1))
1113 {
1115 return;
1116 }
1117 if (!normalizePlayerName(playerName2))
1118 {
1120 return;
1121 }
1122
1123 Group* group = GetPlayer()->GetGroup();
1124 if (!group || !group->isRaidGroup())
1125 {
1126 return;
1127 }
1128
1129 if (!group->IsLeader(GetPlayer()->GetGUID()) && !group->IsAssistant(GetPlayer()->GetGUID()))
1130 {
1131 return;
1132 }
1133
1134 //get guid, member may be offline
1135 auto getGuid = [&group](std::string const& playerName)
1136 {
1137 // no player, cheating?
1138 if (!group->GetMemberGUID(playerName))
1139 {
1140 return ObjectGuid::Empty;
1141 }
1142
1143 if (Player* player = ObjectAccessor::FindPlayerByName(playerName.c_str()))
1144 {
1145 return player->GetGUID();
1146 }
1147 else
1148 {
1149 if (ObjectGuid guid = sCharacterCache->GetCharacterGuidByName(playerName))
1150 {
1151 return guid;
1152 }
1153 else
1154 {
1155 return ObjectGuid::Empty; // no player - again, cheating?
1156 }
1157 }
1158 };
1159
1160 ObjectGuid guid1 = getGuid(playerName1);
1161 ObjectGuid guid2 = getGuid(playerName2);
1162
1163 if (!guid1 || !guid2)
1164 {
1166 return;
1167 }
1168
1169 uint8 groupId1 = group->GetMemberGroup(guid1);
1170 uint8 groupId2 = group->GetMemberGroup(guid2);
1171
1172 if (groupId1 == MAX_RAID_SUBGROUPS + 1 || groupId2 == MAX_RAID_SUBGROUPS + 1)
1173 {
1174 return;
1175 }
1176
1177 if (groupId1 == groupId2)
1178 {
1179 return;
1180 }
1181
1182 group->ChangeMembersGroup(guid1, groupId2);
1183 group->ChangeMembersGroup(guid2, groupId1);
1184}
@ ERR_GROUP_SWAP_FAILED
Definition: SharedDefines.h:3717
@ PARTY_OP_SWAP
Definition: WorldSession.h:194
uint8 GetMemberGroup(ObjectGuid guid) const
Definition: Group.cpp:2384
ObjectGuid GetMemberGUID(const std::string &name)
Definition: Group.cpp:2346
bool isRaidGroup() const
Definition: Group.cpp:2271

References Group::ChangeMembersGroup(), ObjectGuid::Empty, ERR_GROUP_SWAP_FAILED, ObjectAccessor::FindPlayerByName(), Player::GetGroup(), Group::GetMemberGroup(), Group::GetMemberGUID(), GetPlayer(), Group::IsAssistant(), Group::IsLeader(), Group::isRaidGroup(), MAX_RAID_SUBGROUPS, normalizePlayerName(), PARTY_OP_SWAP, sCharacterCache, and SendPartyResult().

Referenced by OpcodeTable::Initialize().

◆ HandleGroupUninviteGuidOpcode()

void WorldSession::HandleGroupUninviteGuidOpcode ( WorldPacket recvPacket)
298{
299 ObjectGuid guid;
300 std::string reason, name;
301 recvData >> guid;
302 recvData >> reason;
303
304 //can't uninvite yourself
305 if (guid == GetPlayer()->GetGUID())
306 {
307 LOG_ERROR("network.opcode", "WorldSession::HandleGroupUninviteGuidOpcode: leader {} ({}) tried to uninvite himself from the group.",
308 GetPlayer()->GetName(), GetPlayer()->GetGUID().ToString());
309 return;
310 }
311
312 sCharacterCache->GetCharacterNameByGuid(guid, name);
313
315 if (res != ERR_PARTY_RESULT_OK)
316 {
318 {
319 if (Player* kickTarget = ObjectAccessor::FindConnectedPlayer(guid))
320 {
321 if (Aura* dungeonCooldownAura = kickTarget->GetAura(lfg::LFG_SPELL_DUNGEON_COOLDOWN))
322 {
323 int32 elapsedTime = dungeonCooldownAura->GetMaxDuration() - dungeonCooldownAura->GetDuration();
324 if (static_cast<int32>(sWorld->getIntConfig(CONFIG_LFG_KICK_PREVENTION_TIMER)) > elapsedTime)
325 {
326 SendPartyResult(PARTY_OP_UNINVITE, name, res, (sWorld->getIntConfig(CONFIG_LFG_KICK_PREVENTION_TIMER) - elapsedTime) / 1000);
327 }
328 }
329 }
330 } else
331 {
333 }
334
335 return;
336 }
337
338 Group* grp = GetPlayer()->GetGroup();
339 if (!grp)
340 return;
341
342 // Xinef: do not allow to kick with empty reason, this will resend packet with given reason
343 if (grp->isLFGGroup(true) && reason.empty())
344 {
346 return;
347 }
348
349 if (grp->IsLeader(guid) && !grp->isLFGGroup(true))
350 {
352 return;
353 }
354
355 if (grp->IsMember(guid))
356 {
357 Player::RemoveFromGroup(grp, guid, GROUP_REMOVEMETHOD_KICK, GetPlayer()->GetGUID(), reason.c_str());
358 return;
359 }
360
361 if (Player* player = grp->GetInvited(guid))
362 {
363 player->UninviteFromGroup();
364 return;
365 }
366
368}
@ CONFIG_LFG_KICK_PREVENTION_TIMER
Definition: IWorld.h:417
@ GROUP_REMOVEMETHOD_KICK
Definition: SharedDefines.h:3588
PartyResult
Definition: SharedDefines.h:3704
@ ERR_PARTY_LFG_BOOT_NOT_ELIGIBLE_S
Definition: SharedDefines.h:3727
@ ERR_VOTE_KICK_REASON_NEEDED
Definition: SharedDefines.h:3730
@ ERR_TARGET_NOT_IN_GROUP_S
Definition: SharedDefines.h:3707
@ PARTY_OP_UNINVITE
Definition: WorldSession.h:192
@ LFG_SPELL_DUNGEON_COOLDOWN
Definition: LFGMgr.h:52
PartyResult CanUninviteFromGroup(ObjectGuid targetPlayerGUID=ObjectGuid::Empty) const
Definition: Player.cpp:13012
Player * GetInvited(ObjectGuid guid) const
Definition: Group.cpp:372
bool IsMember(ObjectGuid guid) const
Definition: Group.cpp:2336
Definition: SpellAuras.h:87

References Player::CanUninviteFromGroup(), CONFIG_LFG_KICK_PREVENTION_TIMER, ERR_NOT_LEADER, ERR_PARTY_LFG_BOOT_NOT_ELIGIBLE_S, ERR_PARTY_RESULT_OK, ERR_TARGET_NOT_IN_GROUP_S, ERR_VOTE_KICK_REASON_NEEDED, ObjectAccessor::FindConnectedPlayer(), Player::GetGroup(), Group::GetInvited(), GetPlayer(), GROUP_REMOVEMETHOD_KICK, Group::IsLeader(), Group::isLFGGroup(), Group::IsMember(), lfg::LFG_SPELL_DUNGEON_COOLDOWN, LOG_ERROR, PARTY_OP_UNINVITE, Player::RemoveFromGroup(), sCharacterCache, SendPartyResult(), and sWorld.

Referenced by OpcodeTable::Initialize().

◆ HandleGroupUninviteOpcode()

void WorldSession::HandleGroupUninviteOpcode ( WorldPacket recvPacket)
371{
372 std::string membername;
373 recvData >> membername;
374
375 // player not found
376 if (!normalizePlayerName(membername))
377 return;
378
379 // can't uninvite yourself
380 if (GetPlayer()->GetName() == membername)
381 {
382 LOG_ERROR("network.opcode", "WorldSession::HandleGroupUninviteOpcode: leader {} ({}) tried to uninvite himself from the group.",
383 GetPlayer()->GetName(), GetPlayer()->GetGUID().ToString());
384 return;
385 }
386
387 Group* grp = GetPlayer()->GetGroup();
388 if (!grp)
389 {
390 return;
391 }
392
393 PartyResult res = GetPlayer()->CanUninviteFromGroup(grp->GetMemberGUID(membername));
394 if (res != ERR_PARTY_RESULT_OK)
395 {
397 return;
398 }
399
400 if (ObjectGuid guid = grp->GetMemberGUID(membername))
401 {
403 return;
404 }
405
406 if (Player* player = grp->GetInvited(membername))
407 {
408 player->UninviteFromGroup();
409 return;
410 }
411
413}

References Player::CanUninviteFromGroup(), ERR_PARTY_RESULT_OK, ERR_TARGET_NOT_IN_GROUP_S, Player::GetGroup(), Group::GetInvited(), Group::GetMemberGUID(), GetPlayer(), GROUP_REMOVEMETHOD_KICK, LOG_ERROR, normalizePlayerName(), PARTY_OP_UNINVITE, Player::RemoveFromGroup(), and SendPartyResult().

Referenced by OpcodeTable::Initialize().

◆ HandleGuildAcceptOpcode()

void WorldSession::HandleGuildAcceptOpcode ( WorldPackets::Guild::AcceptGuildInvite invite)
59{
60 LOG_DEBUG("guild", "CMSG_GUILD_ACCEPT [{}]", GetPlayer()->GetName());
61
62 if (!GetPlayer()->GetGuildId())
63 if (Guild* guild = sGuildMgr->GetGuildById(GetPlayer()->GetGuildIdInvited()))
64 guild->HandleAcceptMember(this);
65}

References GetPlayer(), LOG_DEBUG, and sGuildMgr.

Referenced by OpcodeTable::Initialize().

◆ HandleGuildAddRankOpcode()

void WorldSession::HandleGuildAddRankOpcode ( WorldPackets::Guild::GuildAddRank packet)
201{
202 LOG_DEBUG("guild", "CMSG_GUILD_ADD_RANK [{}]: Rank: {}", GetPlayerInfo(), packet.Name);
203
204 if (Guild* guild = GetPlayer()->GetGuild())
205 guild->HandleAddNewRank(this, packet.Name);
206}
String< 15, Strings::NoHyperlinks > Name
Definition: GuildPackets.h:291

References GetPlayer(), GetPlayerInfo(), LOG_DEBUG, and WorldPackets::Guild::GuildAddRank::Name.

Referenced by OpcodeTable::Initialize().

◆ HandleGuildBankBuyTab()

void WorldSession::HandleGuildBankBuyTab ( WorldPackets::Guild::GuildBankBuyTab packet)
361{
362 LOG_DEBUG("guild", "CMSG_GUILD_BANK_BUY_TAB [{}]: [{}[, TabId: {}", GetPlayerInfo(), packet.Banker .ToString(), packet.BankTab);
363
364 if (GetPlayer()->GetGameObjectIfCanInteractWith(packet.Banker, GAMEOBJECT_TYPE_GUILD_BANK))
365 if (Guild* guild = GetPlayer()->GetGuild())
366 guild->HandleBuyBankTab(this, packet.BankTab);
367}
@ GAMEOBJECT_TYPE_GUILD_BANK
Definition: SharedDefines.h:1594
ObjectGuid Banker
Definition: GuildPackets.h:387
uint8 BankTab
Definition: GuildPackets.h:388

References WorldPackets::Guild::GuildBankBuyTab::Banker, WorldPackets::Guild::GuildBankBuyTab::BankTab, GAMEOBJECT_TYPE_GUILD_BANK, GetPlayer(), GetPlayerInfo(), LOG_DEBUG, and ObjectGuid::ToString().

Referenced by OpcodeTable::Initialize().

◆ HandleGuildBankDepositMoney()

void WorldSession::HandleGuildBankDepositMoney ( WorldPackets::Guild::GuildBankDepositMoney packet)
302{
303 LOG_DEBUG("guild", "CMSG_GUILD_BANK_DEPOSIT_MONEY [{}]: Go: [{}], money: {}",
304 GetPlayerInfo(), packet.Banker.ToString(), packet.Money);
305
306 if (GetPlayer()->GetGameObjectIfCanInteractWith(packet.Banker, GAMEOBJECT_TYPE_GUILD_BANK))
307 if (packet.Money && GetPlayer()->HasEnoughMoney(packet.Money))
308 if (Guild* guild = GetPlayer()->GetGuild())
309 guild->HandleMemberDepositMoney(this, packet.Money);
310}
uint32 Money
Definition: GuildPackets.h:412
ObjectGuid Banker
Definition: GuildPackets.h:411

References WorldPackets::Guild::GuildBankDepositMoney::Banker, GAMEOBJECT_TYPE_GUILD_BANK, GetPlayer(), GetPlayerInfo(), LOG_DEBUG, WorldPackets::Guild::GuildBankDepositMoney::Money, and ObjectGuid::ToString().

Referenced by OpcodeTable::Initialize().

◆ HandleGuildBankerActivate()

void WorldSession::HandleGuildBankerActivate ( WorldPackets::Guild::GuildBankActivate packet)
272{
273 LOG_DEBUG("guild", "CMSG_GUILD_BANKER_ACTIVATE [{}]: Go: [{}] AllSlots: {}"
274 , GetPlayerInfo(), packet.Banker.ToString(), packet.FullUpdate);
275
277 if (!go)
278 return;
279
280 Guild* const guild = GetPlayer()->GetGuild();
281 if (!guild)
282 {
284 return;
285 }
286
287 guild->SendBankTabsInfo(this, packet.FullUpdate);
288}
@ GUILD_COMMAND_VIEW_TAB
Definition: Guild.h:115
@ ERR_GUILD_PLAYER_NOT_IN_GUILD
Definition: Guild.h:132
Guild * GetGuild() const
Definition: Player.cpp:16009
void SendBankTabsInfo(WorldSession *session, bool showTabs=false)
Definition: Guild.cpp:1817
static void SendCommandResult(WorldSession *session, GuildCommandType type, GuildCommandError errCode, std::string_view param={})
Definition: Guild.cpp:114
bool FullUpdate
Definition: GuildPackets.h:377
ObjectGuid Banker
Definition: GuildPackets.h:376

References WorldPackets::Guild::GuildBankActivate::Banker, ERR_GUILD_PLAYER_NOT_IN_GUILD, WorldPackets::Guild::GuildBankActivate::FullUpdate, GAMEOBJECT_TYPE_GUILD_BANK, Player::GetGameObjectIfCanInteractWith(), Player::GetGuild(), GetPlayer(), GetPlayerInfo(), GUILD_COMMAND_VIEW_TAB, LOG_DEBUG, Guild::SendBankTabsInfo(), Guild::SendCommandResult(), and ObjectGuid::ToString().

Referenced by OpcodeTable::Initialize().

◆ HandleGuildBankLogQuery()

void WorldSession::HandleGuildBankLogQuery ( WorldPackets::Guild::GuildBankLogQuery packet)
381{
382 LOG_DEBUG("guild", "MSG_GUILD_BANK_LOG_QUERY [{}]: TabId: {}", GetPlayerInfo(), packet.Tab);
383
384 if (Guild* guild = GetPlayer()->GetGuild())
385 guild->SendBankLog(this, packet.Tab);
386}
uint8 Tab
Definition: GuildPackets.h:531

References GetPlayer(), GetPlayerInfo(), LOG_DEBUG, and WorldPackets::Guild::GuildBankLogQuery::Tab.

Referenced by OpcodeTable::Initialize().

◆ HandleGuildBankMoneyWithdrawn()

void WorldSession::HandleGuildBankMoneyWithdrawn ( WorldPackets::Guild::GuildBankRemainingWithdrawMoneyQuery packet)
257{
258 LOG_DEBUG("guild", "MSG_GUILD_BANK_MONEY_WITHDRAWN [{}]", GetPlayerInfo());
259
260 if (Guild* guild = GetPlayer()->GetGuild())
261 guild->SendMoneyInfo(this);
262}

References GetPlayer(), GetPlayerInfo(), and LOG_DEBUG.

Referenced by OpcodeTable::Initialize().

◆ HandleGuildBankQueryTab()

void WorldSession::HandleGuildBankQueryTab ( WorldPackets::Guild::GuildBankQueryTab packet)
292{
293 LOG_DEBUG("guild", "CMSG_GUILD_BANK_QUERY_TAB [{}]: Go: [{}], TabId: {}, ShowTabs: {}"
294 , GetPlayerInfo(), packet.Banker.ToString(), packet.Tab, packet.FullUpdate);
295
296 if (GetPlayer()->GetGameObjectIfCanInteractWith(packet.Banker, GAMEOBJECT_TYPE_GUILD_BANK))
297 if (Guild* guild = GetPlayer()->GetGuild())
298 guild->SendBankTabData(this, packet.Tab, packet.FullUpdate);
299}
bool FullUpdate
Definition: GuildPackets.h:424
uint8 Tab
Definition: GuildPackets.h:423
ObjectGuid Banker
Definition: GuildPackets.h:422

References WorldPackets::Guild::GuildBankQueryTab::Banker, WorldPackets::Guild::GuildBankQueryTab::FullUpdate, GAMEOBJECT_TYPE_GUILD_BANK, GetPlayer(), GetPlayerInfo(), LOG_DEBUG, WorldPackets::Guild::GuildBankQueryTab::Tab, and ObjectGuid::ToString().

Referenced by OpcodeTable::Initialize().

◆ HandleGuildBankSwapItems()

void WorldSession::HandleGuildBankSwapItems ( WorldPackets::Guild::GuildBankSwapItems packet)
322{
323 if (!GetPlayer()->GetGameObjectIfCanInteractWith(packet.Banker, GAMEOBJECT_TYPE_GUILD_BANK))
324 {
325 return;
326 }
327
328 Guild* guild = GetPlayer()->GetGuild();
329 if (!guild)
330 {
331 return;
332 }
333
334 if (packet.BankOnly)
335 guild->SwapItems(GetPlayer(), packet.BankTab1, packet.BankSlot1, packet.BankTab, packet.BankSlot, packet.BankItemCount);
336 else
337 {
338 uint8 playerBag = NULL_BAG;
339 uint8 playerSlotId = NULL_SLOT;
340 uint8 toChar = 1;
341 uint32 splitedAmount = 0;
342
343 if (!packet.AutoStore)
344 {
345 playerBag = packet.ContainerSlot;
346 playerSlotId = packet.ContainerItemSlot;
347 toChar = packet.ToSlot;
348 splitedAmount = packet.StackCount;
349 }
350
351 // Player <-> Bank
352 // Allow to work with inventory only
353 if (!Player::IsInventoryPos(playerBag, playerSlotId) && !(playerBag == NULL_BAG && playerSlotId == NULL_SLOT))
355 else
356 guild->SwapItemsWithInventory(GetPlayer(), toChar != 0, packet.BankTab, packet.BankSlot, playerBag, playerSlotId, splitedAmount);
357 }
358}
void SwapItemsWithInventory(Player *player, bool toChar, uint8 tabId, uint8 slotId, uint8 playerBag, uint8 playerSlotId, uint32 splitedAmount)
Definition: Guild.cpp:2357
void SwapItems(Player *player, uint8 tabId, uint8 slotId, uint8 destTabId, uint8 destSlotId, uint32 splitedAmount)
Definition: Guild.cpp:2343
uint8 ContainerSlot
Definition: GuildPackets.h:518
uint8 ToSlot
Definition: GuildPackets.h:513
bool BankOnly
Definition: GuildPackets.h:521
uint8 ContainerItemSlot
Definition: GuildPackets.h:519
uint8 BankTab
Definition: GuildPackets.h:516
ObjectGuid Banker
Definition: GuildPackets.h:508
uint8 BankTab1
Definition: GuildPackets.h:517
uint8 BankSlot
Definition: GuildPackets.h:514
bool AutoStore
Definition: GuildPackets.h:520
uint8 BankSlot1
Definition: GuildPackets.h:515
int32 BankItemCount
Definition: GuildPackets.h:510
int32 StackCount
Definition: GuildPackets.h:509

References WorldPackets::Guild::GuildBankSwapItems::AutoStore, WorldPackets::Guild::GuildBankSwapItems::Banker, WorldPackets::Guild::GuildBankSwapItems::BankItemCount, WorldPackets::Guild::GuildBankSwapItems::BankOnly, WorldPackets::Guild::GuildBankSwapItems::BankSlot, WorldPackets::Guild::GuildBankSwapItems::BankSlot1, WorldPackets::Guild::GuildBankSwapItems::BankTab, WorldPackets::Guild::GuildBankSwapItems::BankTab1, WorldPackets::Guild::GuildBankSwapItems::ContainerItemSlot, WorldPackets::Guild::GuildBankSwapItems::ContainerSlot, EQUIP_ERR_NONE, GAMEOBJECT_TYPE_GUILD_BANK, Player::GetGuild(), GetPlayer(), Player::IsInventoryPos(), NULL_BAG, NULL_SLOT, Player::SendEquipError(), WorldPackets::Guild::GuildBankSwapItems::StackCount, Guild::SwapItems(), Guild::SwapItemsWithInventory(), and WorldPackets::Guild::GuildBankSwapItems::ToSlot.

Referenced by OpcodeTable::Initialize().

◆ HandleGuildBankUpdateTab()

void WorldSession::HandleGuildBankUpdateTab ( WorldPackets::Guild::GuildBankUpdateTab packet)
370{
371 LOG_DEBUG("guild", "CMSG_GUILD_BANK_UPDATE_TAB [{}]: Go: [{}], TabId: {}, Name: {}, Icon: {}"
372 , GetPlayerInfo(), packet.Banker.ToString(), packet.BankTab, packet.Name, packet.Icon);
373
374 if (!packet.Name.empty() && !packet.Icon.empty())
375 if (GetPlayer()->GetGameObjectIfCanInteractWith(packet.Banker, GAMEOBJECT_TYPE_GUILD_BANK))
376 if (Guild* guild = GetPlayer()->GetGuild())
377 guild->HandleSetBankTabInfo(this, packet.BankTab, packet.Name, packet.Icon);
378}
String< 16, Strings::NoHyperlinks > Name
Definition: GuildPackets.h:400
uint8 BankTab
Definition: GuildPackets.h:399
String< 100 > Icon
Definition: GuildPackets.h:401
ObjectGuid Banker
Definition: GuildPackets.h:398
bool empty() const
Definition: PacketUtilities.h:78

References WorldPackets::Guild::GuildBankUpdateTab::Banker, WorldPackets::Guild::GuildBankUpdateTab::BankTab, WorldPackets::String< MaxBytesWithoutNullTerminator, Validators >::empty(), GAMEOBJECT_TYPE_GUILD_BANK, GetPlayer(), GetPlayerInfo(), WorldPackets::Guild::GuildBankUpdateTab::Icon, LOG_DEBUG, WorldPackets::Guild::GuildBankUpdateTab::Name, and ObjectGuid::ToString().

Referenced by OpcodeTable::Initialize().

◆ HandleGuildBankWithdrawMoney()

void WorldSession::HandleGuildBankWithdrawMoney ( WorldPackets::Guild::GuildBankWithdrawMoney packet)
313{
314 LOG_DEBUG("guild", "CMSG_GUILD_BANK_WITHDRAW_MONEY [{}]: Go: [{}], money: {}",
315 GetPlayerInfo(), packet.Banker.ToString(), packet.Money);
316 if (packet.Money && GetPlayer()->GetGameObjectIfCanInteractWith(packet.Banker, GAMEOBJECT_TYPE_GUILD_BANK))
317 if (Guild* guild = GetPlayer()->GetGuild())
318 guild->HandleMemberWithdrawMoney(this, packet.Money);
319}
uint32 Money
Definition: GuildPackets.h:453
ObjectGuid Banker
Definition: GuildPackets.h:452

References WorldPackets::Guild::GuildBankWithdrawMoney::Banker, GAMEOBJECT_TYPE_GUILD_BANK, GetPlayer(), GetPlayerInfo(), LOG_DEBUG, WorldPackets::Guild::GuildBankWithdrawMoney::Money, and ObjectGuid::ToString().

Referenced by OpcodeTable::Initialize().

◆ HandleGuildChangeInfoTextOpcode()

void WorldSession::HandleGuildChangeInfoTextOpcode ( WorldPackets::Guild::GuildUpdateInfoText packet)
217{
218 LOG_DEBUG("guild", "CMSG_GUILD_INFO_TEXT [{}]: {}", GetPlayerInfo(), packet.InfoText);
219
220 if (Guild* guild = GetPlayer()->GetGuild())
221 guild->HandleSetInfo(this, packet.InfoText);
222}
String< 500, Strings::NoHyperlinks > InfoText
Definition: GuildPackets.h:309

References GetPlayer(), GetPlayerInfo(), WorldPackets::Guild::GuildUpdateInfoText::InfoText, and LOG_DEBUG.

Referenced by OpcodeTable::Initialize().

◆ HandleGuildCreateOpcode()

void WorldSession::HandleGuildCreateOpcode ( WorldPackets::Guild::GuildCreate packet)
37{
38 LOG_ERROR("network.opcode", "CMSG_GUILD_CREATE: Possible hacking-attempt: {} tried to create a guild [Name: {}] using cheats", GetPlayerInfo(), packet.GuildName);
39}
std::string GuildName
Definition: GuildPackets.h:73

References GetPlayerInfo(), WorldPackets::Guild::GuildCreate::GuildName, and LOG_ERROR.

Referenced by OpcodeTable::Initialize().

◆ HandleGuildDeclineOpcode()

void WorldSession::HandleGuildDeclineOpcode ( WorldPackets::Guild::GuildDeclineInvitation decline)
68{
69 LOG_DEBUG("guild", "CMSG_GUILD_DECLINE [{}]", GetPlayerInfo());
70
71 if (GetPlayer()->GetGuild())
72 {
73 return;
74 }
75
78}
void SetGuildIdInvited(uint32 GuildId)
Definition: Player.h:1882
void SetInGuild(uint32 GuildId)
Definition: Player.h:1874

References GetPlayer(), GetPlayerInfo(), LOG_DEBUG, Player::SetGuildIdInvited(), and Player::SetInGuild().

Referenced by OpcodeTable::Initialize().

◆ HandleGuildDelRankOpcode()

void WorldSession::HandleGuildDelRankOpcode ( WorldPackets::Guild::GuildDeleteRank packet)
209{
210 LOG_DEBUG("guild", "CMSG_GUILD_DEL_RANK [{}]", GetPlayerInfo());
211
212 if (Guild* guild = GetPlayer()->GetGuild())
213 guild->HandleRemoveLowestRank(this);
214}

References GetPlayer(), GetPlayerInfo(), and LOG_DEBUG.

Referenced by OpcodeTable::Initialize().

◆ HandleGuildDemoteOpcode()

void WorldSession::HandleGuildDemoteOpcode ( WorldPackets::Guild::GuildDemoteMember demote)
108{
109 LOG_DEBUG("guild", "CMSG_GUILD_DEMOTE [{}]: Target: {}", GetPlayerInfo(), demote.Demotee);
110
111 if (normalizePlayerName(demote.Demotee))
112 if (Guild* guild = GetPlayer()->GetGuild())
113 guild->HandleUpdateMemberRank(this, demote.Demotee, true);
114}
std::string Demotee
Definition: GuildPackets.h:338

References WorldPackets::Guild::GuildDemoteMember::Demotee, GetPlayer(), GetPlayerInfo(), LOG_DEBUG, and normalizePlayerName().

Referenced by OpcodeTable::Initialize().

◆ HandleGuildDisbandOpcode()

void WorldSession::HandleGuildDisbandOpcode ( WorldPackets::Guild::GuildDelete packet)
125{
126 LOG_DEBUG("guild", "CMSG_GUILD_DISBAND [{}]", GetPlayerInfo());
127
128 if (Guild* guild = GetPlayer()->GetGuild())
129 guild->HandleDisband(this);
130}

References GetPlayer(), GetPlayerInfo(), and LOG_DEBUG.

Referenced by OpcodeTable::Initialize().

◆ HandleGuildEventLogQueryOpcode()

void WorldSession::HandleGuildEventLogQueryOpcode ( WorldPackets::Guild::GuildEventLogQuery packet)
249{
250 LOG_DEBUG("guild", "MSG_GUILD_EVENT_LOG_QUERY [{}]", GetPlayerInfo());
251
252 if (Guild* guild = GetPlayer()->GetGuild())
253 guild->SendEventLog(this);
254}

References GetPlayer(), GetPlayerInfo(), and LOG_DEBUG.

Referenced by OpcodeTable::Initialize().

◆ HandleGuildInfoOpcode()

void WorldSession::HandleGuildInfoOpcode ( WorldPackets::Guild::GuildGetInfo packet)
81{
82 LOG_DEBUG("guild", "CMSG_GUILD_INFO [{}]", GetPlayerInfo());
83
84 if (Guild* guild = GetPlayer()->GetGuild())
85 guild->SendInfo(this);
86}

References GetPlayer(), GetPlayerInfo(), and LOG_DEBUG.

Referenced by OpcodeTable::Initialize().

◆ HandleGuildInviteOpcode()

void WorldSession::HandleGuildInviteOpcode ( WorldPackets::Guild::GuildInviteByName packet)
42{
43 LOG_DEBUG("guild", "CMSG_GUILD_INVITE [{}]: Invited: {}", GetPlayerInfo(), packet.Name);
44 if (normalizePlayerName(packet.Name))
45 if (Guild* guild = GetPlayer()->GetGuild())
46 guild->HandleInviteMember(this, packet.Name);
47}
String< 48 > Name
Definition: GuildPackets.h:188

References GetPlayer(), GetPlayerInfo(), LOG_DEBUG, WorldPackets::Guild::GuildInviteByName::Name, and normalizePlayerName().

Referenced by OpcodeTable::Initialize().

◆ HandleGuildLeaderOpcode()

void WorldSession::HandleGuildLeaderOpcode ( WorldPackets::Guild::GuildSetGuildMaster packet)
133{
134 LOG_DEBUG("guild", "CMSG_GUILD_LEADER [{}]: Target: {}", GetPlayerInfo(), packet.NewMasterName);
135
137 if (Guild* guild = GetPlayer()->GetGuild())
138 guild->HandleSetLeader(this, packet.NewMasterName);
139}
std::string NewMasterName
Definition: GuildPackets.h:595

References GetPlayer(), GetPlayerInfo(), LOG_DEBUG, WorldPackets::Guild::GuildSetGuildMaster::NewMasterName, and normalizePlayerName().

Referenced by OpcodeTable::Initialize().

◆ HandleGuildLeaveOpcode()

void WorldSession::HandleGuildLeaveOpcode ( WorldPackets::Guild::GuildLeave leave)
117{
118 LOG_DEBUG("guild", "CMSG_GUILD_LEAVE [{}]", GetPlayerInfo());
119
120 if (Guild* guild = GetPlayer()->GetGuild())
121 guild->HandleLeaveMember(this);
122}

References GetPlayer(), GetPlayerInfo(), and LOG_DEBUG.

Referenced by OpcodeTable::Initialize().

◆ HandleGuildMOTDOpcode()

void WorldSession::HandleGuildMOTDOpcode ( WorldPackets::Guild::GuildUpdateMotdText packet)
142{
143 LOG_DEBUG("guild", "CMSG_GUILD_MOTD [{}]: MOTD: {}", GetPlayerInfo(), packet.MotdText);
144
145 if (Guild* guild = GetPlayer()->GetGuild())
146 guild->HandleSetMOTD(this, packet.MotdText);
147}
String< 128, Strings::NoHyperlinks > MotdText
Definition: GuildPackets.h:150

References GetPlayer(), GetPlayerInfo(), LOG_DEBUG, and WorldPackets::Guild::GuildUpdateMotdText::MotdText.

Referenced by OpcodeTable::Initialize().

◆ HandleGuildPermissions()

void WorldSession::HandleGuildPermissions ( WorldPackets::Guild::GuildPermissionsQuery packet)
265{
266 if (Guild* guild = GetPlayer()->GetGuild())
267 guild->SendPermissions(this);
268}

References GetPlayer().

Referenced by OpcodeTable::Initialize().

◆ HandleGuildPromoteOpcode()

void WorldSession::HandleGuildPromoteOpcode ( WorldPackets::Guild::GuildPromoteMember promote)
99{
100 LOG_DEBUG("guild", "CMSG_GUILD_PROMOTE [{}]: Target: {}", GetPlayerInfo(), promote.Promotee);
101
102 if (normalizePlayerName(promote.Promotee))
103 if (Guild* guild = GetPlayer()->GetGuild())
104 guild->HandleUpdateMemberRank(this, promote.Promotee, false);
105}
std::string Promotee
Definition: GuildPackets.h:348

References GetPlayer(), GetPlayerInfo(), LOG_DEBUG, normalizePlayerName(), and WorldPackets::Guild::GuildPromoteMember::Promotee.

Referenced by OpcodeTable::Initialize().

◆ HandleGuildQueryOpcode()

void WorldSession::HandleGuildQueryOpcode ( WorldPackets::Guild::QueryGuildInfo query)
27{
28 LOG_DEBUG("guild", "CMSG_GUILD_QUERY [{}]: Guild: {}", GetPlayerInfo(), query.GuildId);
29 if (!query.GuildId)
30 return;
31
32 if (Guild* guild = sGuildMgr->GetGuildById(query.GuildId))
33 guild->HandleQuery(this);
34}
uint32 GuildId
Definition: GuildPackets.h:38

References GetPlayerInfo(), WorldPackets::Guild::QueryGuildInfo::GuildId, LOG_DEBUG, and sGuildMgr.

Referenced by OpcodeTable::Initialize().

◆ HandleGuildRankOpcode()

void WorldSession::HandleGuildRankOpcode ( WorldPackets::Guild::GuildSetRankPermissions packet)
169{
170 Guild* guild = GetPlayer()->GetGuild();
171 if (!guild)
172 {
173 return;
174 }
175
176 std::array<GuildBankRightsAndSlots, GUILD_BANK_MAX_TABS> rightsAndSlots;
177
178 for (uint8 tabId = 0; tabId < GUILD_BANK_MAX_TABS; ++tabId)
179 {
180 // For some reason the client is sending - 1 for guildmaster tab withdraw item limit, that's ilegal for us because we expect unsigned int.
181 // Probably core handling for this should be changed.
182 if (packet.TabWithdrawItemLimit[tabId] <= 0)
183 {
185 }
186 rightsAndSlots[tabId] = GuildBankRightsAndSlots(tabId, uint8(packet.TabFlags[tabId]), packet.TabWithdrawItemLimit[tabId]);
187 }
188
189 LOG_DEBUG("guild", "CMSG_GUILD_RANK [{}]: Rank: {} ({})", GetPlayerInfo(), packet.RankName, packet.RankID);
190
191 // Same as the issue above but this time with rights.
192 if (packet.Flags <= 0)
193 {
195 }
196
197 guild->HandleSetRankInfo(this, packet.RankID, packet.RankName, packet.Flags, packet.WithdrawGoldLimit, rightsAndSlots);
198}
@ GUILD_WITHDRAW_SLOT_UNLIMITED
Definition: Guild.h:52
@ GUILD_BANK_MAX_TABS
Definition: Guild.h:45
@ GUILD_BANK_RIGHT_FULL
Definition: Guild.h:195
Definition: Guild.h:266
void HandleSetRankInfo(WorldSession *session, uint8 rankId, std::string_view name, uint32 rights, uint32 moneyPerDay, std::array< GuildBankRightsAndSlots, GUILD_BANK_MAX_TABS > const &rightsAndSlots)
Definition: Guild.cpp:1383
uint32 RankID
Definition: GuildPackets.h:276
uint32 WithdrawGoldLimit
Definition: GuildPackets.h:277
String< 15, Strings::NoHyperlinks > RankName
Definition: GuildPackets.h:281
uint32 TabWithdrawItemLimit[GUILD_BANK_MAX_TABS]
Definition: GuildPackets.h:280
uint32 Flags
Definition: GuildPackets.h:278
uint32 TabFlags[GUILD_BANK_MAX_TABS]
Definition: GuildPackets.h:279

References WorldPackets::Guild::GuildSetRankPermissions::Flags, Player::GetGuild(), GetPlayer(), GetPlayerInfo(), GUILD_BANK_MAX_TABS, GUILD_BANK_RIGHT_FULL, GUILD_WITHDRAW_SLOT_UNLIMITED, Guild::HandleSetRankInfo(), LOG_DEBUG, WorldPackets::Guild::GuildSetRankPermissions::RankID, WorldPackets::Guild::GuildSetRankPermissions::RankName, WorldPackets::Guild::GuildSetRankPermissions::TabFlags, WorldPackets::Guild::GuildSetRankPermissions::TabWithdrawItemLimit, and WorldPackets::Guild::GuildSetRankPermissions::WithdrawGoldLimit.

Referenced by OpcodeTable::Initialize().

◆ HandleGuildRemoveOpcode()

void WorldSession::HandleGuildRemoveOpcode ( WorldPackets::Guild::GuildOfficerRemoveMember packet)
50{
51 LOG_DEBUG("guild", "CMSG_GUILD_REMOVE [{}]: Target: {}", GetPlayerInfo(), packet.Removee);
52
53 if (normalizePlayerName(packet.Removee))
54 if (Guild* guild = GetPlayer()->GetGuild())
55 guild->HandleRemoveMember(this, packet.Removee);
56}
std::string Removee
Definition: GuildPackets.h:358

References GetPlayer(), GetPlayerInfo(), LOG_DEBUG, normalizePlayerName(), and WorldPackets::Guild::GuildOfficerRemoveMember::Removee.

Referenced by OpcodeTable::Initialize().

◆ HandleGuildRosterOpcode()

void WorldSession::HandleGuildRosterOpcode ( WorldPackets::Guild::GuildGetRoster packet)
89{
90 LOG_DEBUG("guild", "CMSG_GUILD_ROSTER [{}]", GetPlayerInfo());
91
92 if (Guild* guild = GetPlayer()->GetGuild())
93 guild->HandleRoster(this);
94 else
96}
@ GUILD_COMMAND_ROSTER
Definition: Guild.h:105

References ERR_GUILD_PLAYER_NOT_IN_GUILD, GetPlayer(), GetPlayerInfo(), GUILD_COMMAND_ROSTER, LOG_DEBUG, and Guild::SendCommandResult().

Referenced by OpcodeTable::Initialize().

◆ HandleGuildSetOfficerNoteOpcode()

void WorldSession::HandleGuildSetOfficerNoteOpcode ( WorldPackets::Guild::GuildSetMemberNote packet)
159{
160 LOG_DEBUG("guild", "CMSG_GUILD_SET_OFFICER_NOTE [{}]: Target: {}, Note: {}",
161 GetPlayerInfo(), packet.NoteeName, packet.Note);
162
163 if (normalizePlayerName(packet.NoteeName))
164 if (Guild* guild = GetPlayer()->GetGuild())
165 guild->HandleSetMemberNote(this, packet.NoteeName, packet.Note, false);
166}
String< 31, Strings::NoHyperlinks > Note
Definition: GuildPackets.h:320
std::string NoteeName
Definition: GuildPackets.h:319

References GetPlayer(), GetPlayerInfo(), LOG_DEBUG, normalizePlayerName(), WorldPackets::Guild::GuildSetMemberNote::Note, and WorldPackets::Guild::GuildSetMemberNote::NoteeName.

Referenced by OpcodeTable::Initialize().

◆ HandleGuildSetPublicNoteOpcode()

void WorldSession::HandleGuildSetPublicNoteOpcode ( WorldPackets::Guild::GuildSetMemberNote packet)
150{
151 LOG_DEBUG("guild", "CMSG_GUILD_SET_PUBLIC_NOTE [{}]: Target: {}, Note: {}", GetPlayerInfo(), packet.NoteeName, packet.Note);
152
153 if (normalizePlayerName(packet.NoteeName))
154 if (Guild* guild = GetPlayer()->GetGuild())
155 guild->HandleSetMemberNote(this, packet.NoteeName, packet.Note, true);
156}

References GetPlayer(), GetPlayerInfo(), LOG_DEBUG, normalizePlayerName(), WorldPackets::Guild::GuildSetMemberNote::Note, and WorldPackets::Guild::GuildSetMemberNote::NoteeName.

Referenced by OpcodeTable::Initialize().

◆ HandleHearthAndResurrect()

void WorldSession::HandleHearthAndResurrect ( WorldPacket recvData)
1706{
1707 if (_player->IsInFlight())
1708 return;
1709
1710 if (Battlefield* bf = sBattlefieldMgr->GetBattlefieldToZoneId(_player->GetZoneId()))
1711 {
1712 bf->PlayerAskToLeave(_player);
1713 return;
1714 }
1715
1716 AreaTableEntry const* atEntry = sAreaTableStore.LookupEntry(_player->GetAreaId());
1717 if (!atEntry || !(atEntry->flags & AREA_FLAG_WINTERGRASP_2))
1718 return;
1719
1721 _player->ResurrectPlayer(1.0f);
1724}
@ AREA_FLAG_WINTERGRASP_2
Definition: DBCEnums.h:261
uint32 GetAreaId() const
Definition: Object.cpp:3154
float GetOrientation() const
Definition: Position.h:120
float m_homebindZ
Definition: Player.h:2355
uint32 m_homebindMapId
Definition: Player.h:2351
float m_homebindY
Definition: Player.h:2354
void BuildPlayerRepop()
Definition: Player.cpp:4410
float m_homebindX
Definition: Player.h:2353
uint32 flags
Definition: DBCStructure.h:523

References _player, AREA_FLAG_WINTERGRASP_2, Player::BuildPlayerRepop(), AreaTableEntry::flags, WorldObject::GetAreaId(), Position::GetOrientation(), WorldObject::GetZoneId(), Unit::IsInFlight(), Player::m_homebindMapId, Player::m_homebindX, Player::m_homebindY, Player::m_homebindZ, Player::ResurrectPlayer(), sAreaTableStore, sBattlefieldMgr, Player::SpawnCorpseBones(), and Player::TeleportTo().

Referenced by OpcodeTable::Initialize().

◆ HandleIgnoreTradeOpcode()

void WorldSession::HandleIgnoreTradeOpcode ( WorldPacket recvPacket)
72{
73 LOG_DEBUG("network", "WORLD: Ignore Trade {}", _player->GetGUID().ToString());
74 // recvPacket.print_storage();
75}

References _player, Object::GetGUID(), LOG_DEBUG, and ObjectGuid::ToString().

Referenced by OpcodeTable::Initialize().

◆ HandleInitiateTradeOpcode()

void WorldSession::HandleInitiateTradeOpcode ( WorldPacket recvPacket)
545{
546 ObjectGuid ID;
547 recvPacket >> ID;
548
549 if (GetPlayer()->m_trade)
550 return;
551
552 if (!GetPlayer()->IsAlive())
553 {
555 return;
556 }
557
558 if (GetPlayer()->HasUnitState(UNIT_STATE_STUNNED))
559 {
561 return;
562 }
563
564 if (isLogingOut())
565 {
567 return;
568 }
569
570 if (GetPlayer()->IsInFlight())
571 {
573 return;
574 }
575
576 if (GetPlayer()->GetLevel() < sWorld->getIntConfig(CONFIG_TRADE_LEVEL_REQ))
577 {
579 return;
580 }
581
582 if (GetPlayer()->IsSpectator())
583 return;
584
586
587 if (!pOther)
588 {
590 return;
591 }
592
593 if (pOther == GetPlayer() || pOther->m_trade)
594 {
596 return;
597 }
598
599 if (!pOther->IsAlive())
600 {
602 return;
603 }
604
605 if (pOther->IsInFlight())
606 {
608 return;
609 }
610
611 if (pOther->HasUnitState(UNIT_STATE_STUNNED))
612 {
614 return;
615 }
616
617 if (pOther->GetSession()->isLogingOut())
618 {
620 return;
621 }
622
623 if (pOther->GetSocial()->HasIgnore(GetPlayer()->GetGUID()))
624 {
626 return;
627 }
628
629 if (!sWorld->getBoolConfig(CONFIG_ALLOW_TWO_SIDE_TRADE) && pOther->GetTeamId() != _player->GetTeamId())
630 {
632 return;
633 }
634
635 if (!pOther->IsWithinDistInMap(_player, 10.0f, false))
636 {
638 return;
639 }
640
641 if (pOther->GetLevel() < sWorld->getIntConfig(CONFIG_TRADE_LEVEL_REQ))
642 {
644 return;
645 }
646
647 if (!sScriptMgr->CanInitTrade(_player, pOther))
648 return;
649
650 // OK start trade
651 _player->m_trade = new TradeData(_player, pOther);
652 pOther->m_trade = new TradeData(pOther, _player);
653
656 data << _player->GetGUID();
657 pOther->GetSession()->SendPacket(&data);
658}
@ CONFIG_TRADE_LEVEL_REQ
Definition: IWorld.h:295
@ CONFIG_ALLOW_TWO_SIDE_TRADE
Definition: IWorld.h:82
@ LANG_TRADE_OTHER_REQ
Definition: Language.h:1157
@ LANG_TRADE_REQ
Definition: Language.h:1156
@ UNIT_STATE_STUNNED
Definition: UnitDefines.h:152
@ TRADE_STATUS_YOU_STUNNED
Definition: SharedDefines.h:3565
@ TRADE_STATUS_IGNORE_YOU
Definition: SharedDefines.h:3564
@ TRADE_STATUS_YOU_DEAD
Definition: SharedDefines.h:3567
@ TRADE_STATUS_YOU_LOGOUT
Definition: SharedDefines.h:3569
@ TRADE_STATUS_TARGET_DEAD
Definition: SharedDefines.h:3568
@ TRADE_STATUS_NO_TARGET
Definition: SharedDefines.h:3556
@ TRADE_STATUS_BEGIN_TRADE
Definition: SharedDefines.h:3551
@ TRADE_STATUS_TARGET_LOGOUT
Definition: SharedDefines.h:3570
@ TRADE_STATUS_TARGET_STUNNED
Definition: SharedDefines.h:3566
@ TRADE_STATUS_TARGET_TO_FAR
Definition: SharedDefines.h:3560
@ TRADE_STATUS_BUSY
Definition: SharedDefines.h:3550
@ TRADE_STATUS_WRONG_FACTION
Definition: SharedDefines.h:3561
@ SMSG_TRADE_STATUS
Definition: Opcodes.h:318
bool isLogingOut() const
Is the user engaged in a log out process?
Definition: WorldSession.h:385

References _player, CONFIG_ALLOW_TWO_SIDE_TRADE, CONFIG_TRADE_LEVEL_REQ, ObjectAccessor::FindPlayer(), Object::GetGUID(), Unit::GetLevel(), GetPlayer(), Player::GetSession(), Player::GetSocial(), Player::GetTeamId(), PlayerSocial::HasIgnore(), Unit::HasUnitState(), Unit::IsAlive(), Unit::IsInFlight(), isLogingOut(), WorldObject::IsWithinDistInMap(), LANG_TRADE_OTHER_REQ, LANG_TRADE_REQ, Player::m_trade, ChatHandler::SendNotification(), SendPacket(), SendTradeStatus(), SMSG_TRADE_STATUS, sScriptMgr, sWorld, TRADE_STATUS_BEGIN_TRADE, TRADE_STATUS_BUSY, TRADE_STATUS_IGNORE_YOU, TRADE_STATUS_NO_TARGET, TRADE_STATUS_TARGET_DEAD, TRADE_STATUS_TARGET_LOGOUT, TRADE_STATUS_TARGET_STUNNED, TRADE_STATUS_TARGET_TO_FAR, TRADE_STATUS_WRONG_FACTION, TRADE_STATUS_YOU_DEAD, TRADE_STATUS_YOU_LOGOUT, TRADE_STATUS_YOU_STUNNED, and UNIT_STATE_STUNNED.

Referenced by OpcodeTable::Initialize().

◆ HandleInspectArenaTeamsOpcode()

void WorldSession::HandleInspectArenaTeamsOpcode ( WorldPacket recvData)
30{
31 LOG_DEBUG("network", "MSG_INSPECT_ARENA_TEAMS");
32
33 ObjectGuid guid;
34 recvData >> guid;
35 LOG_DEBUG("network", "Inspect Arena stats ({})", guid.ToString());
36
37 Player* player = ObjectAccessor::FindPlayer(guid);
38 if (!player)
39 {
40 return;
41 }
42
43 if (!GetPlayer()->IsWithinDistInMap(player, INSPECT_DISTANCE, false))
44 {
45 return;
46 }
47
48 if (GetPlayer()->IsValidAttackTarget(player))
49 {
50 return;
51 }
52
53 for (uint8 i = 0; i < MAX_ARENA_SLOT; ++i)
54 {
55 if (uint32 a_id = player->GetArenaTeamId(i))
56 {
57 if (ArenaTeam* arenaTeam = sArenaTeamMgr->GetArenaTeamById(a_id))
58 arenaTeam->Inspect(this, player->GetGUID());
59 }
60 }
61}
#define MAX_ARENA_SLOT
Definition: ArenaTeam.h:134
#define INSPECT_DISTANCE
Definition: ObjectDefines.h:27

References ObjectAccessor::FindPlayer(), Player::GetArenaTeamId(), Object::GetGUID(), GetPlayer(), INSPECT_DISTANCE, LOG_DEBUG, MAX_ARENA_SLOT, sArenaTeamMgr, and ObjectGuid::ToString().

Referenced by OpcodeTable::Initialize().

◆ HandleInspectHonorStatsOpcode()

void WorldSession::HandleInspectHonorStatsOpcode ( WorldPacket recvPacket)
1063{
1064 ObjectGuid guid;
1065 recv_data >> guid;
1066
1067 Player* player = ObjectAccessor::GetPlayer(*_player, guid);
1068 if (!player)
1069 {
1070 LOG_DEBUG("network", "MSG_INSPECT_HONOR_STATS: No player found from {}", guid.ToString());
1071 return;
1072 }
1073
1074 if (!GetPlayer()->IsWithinDistInMap(player, INSPECT_DISTANCE, false))
1075 {
1076 return;
1077 }
1078
1079 if (GetPlayer()->IsValidAttackTarget(player))
1080 {
1081 return;
1082 }
1083
1084 WorldPacket data(MSG_INSPECT_HONOR_STATS, 8 + 1 + 4 * 4);
1085 data << player->GetGUID();
1086 data << uint8(player->GetHonorPoints());
1087 data << uint32(player->GetUInt32Value(PLAYER_FIELD_KILLS));
1091 SendPacket(&data);
1092}
@ PLAYER_FIELD_TODAY_CONTRIBUTION
Definition: UpdateFields.h:375
@ PLAYER_FIELD_KILLS
Definition: UpdateFields.h:374
@ PLAYER_FIELD_YESTERDAY_CONTRIBUTION
Definition: UpdateFields.h:376
@ PLAYER_FIELD_LIFETIME_HONORABLE_KILLS
Definition: UpdateFields.h:377
@ MSG_INSPECT_HONOR_STATS
Definition: Opcodes.h:756
uint32 GetHonorPoints() const
Definition: Player.h:2134

References _player, Object::GetGUID(), Player::GetHonorPoints(), GetPlayer(), ObjectAccessor::GetPlayer(), Object::GetUInt32Value(), INSPECT_DISTANCE, LOG_DEBUG, MSG_INSPECT_HONOR_STATS, PLAYER_FIELD_KILLS, PLAYER_FIELD_LIFETIME_HONORABLE_KILLS, PLAYER_FIELD_TODAY_CONTRIBUTION, PLAYER_FIELD_YESTERDAY_CONTRIBUTION, SendPacket(), and ObjectGuid::ToString().

Referenced by OpcodeTable::Initialize().

◆ HandleInspectOpcode()

void WorldSession::HandleInspectOpcode ( WorldPacket recvPacket)
1021{
1022 ObjectGuid guid;
1023 recv_data >> guid;
1024
1025 Player* player = ObjectAccessor::GetPlayer(*_player, guid);
1026 if (!player)
1027 {
1028 LOG_DEBUG("network", "CMSG_INSPECT: No player found from {}", guid.ToString());
1029 return;
1030 }
1031
1032 if (!GetPlayer()->IsWithinDistInMap(player, INSPECT_DISTANCE, false))
1033 {
1034 return;
1035 }
1036
1037 if (GetPlayer()->IsValidAttackTarget(player))
1038 {
1039 return;
1040 }
1041
1042 uint32 talent_points = 0x47;
1043 uint32 guid_size = player->GetPackGUID().size();
1044 WorldPacket data(SMSG_INSPECT_TALENT, guid_size + 4 + talent_points);
1045 data << player->GetPackGUID();
1046
1047 if (sWorld->getBoolConfig(CONFIG_TALENTS_INSPECTING) || _player->IsGameMaster())
1048 {
1049 player->BuildPlayerTalentsInfoData(&data);
1050 }
1051 else
1052 {
1053 data << uint32(0); // unspentTalentPoints
1054 data << uint8(0); // talentGroupCount
1055 data << uint8(0); // talentGroupIndex
1056 }
1057
1058 player->BuildEnchantmentsInfoData(&data);
1059 SendPacket(&data);
1060}
@ CONFIG_TALENTS_INSPECTING
Definition: IWorld.h:100
@ SMSG_INSPECT_TALENT
Definition: Opcodes.h:1042
std::size_t size() const
Definition: ObjectGuid.h:274
void BuildEnchantmentsInfoData(WorldPacket *data)
Definition: Player.cpp:14435
void BuildPlayerTalentsInfoData(WorldPacket *data)
Definition: Player.cpp:14318

References _player, Player::BuildEnchantmentsInfoData(), Player::BuildPlayerTalentsInfoData(), CONFIG_TALENTS_INSPECTING, Object::GetPackGUID(), GetPlayer(), ObjectAccessor::GetPlayer(), INSPECT_DISTANCE, Player::IsGameMaster(), LOG_DEBUG, SendPacket(), PackedGuid::size(), SMSG_INSPECT_TALENT, sWorld, and ObjectGuid::ToString().

Referenced by OpcodeTable::Initialize().

◆ HandleInstanceLockResponse()

void WorldSession::HandleInstanceLockResponse ( WorldPacket recvPacket)
1727{
1728 uint8 accept;
1729 recvPacket >> accept;
1730
1732 {
1733 LOG_DEBUG("network.opcode", "InstanceLockResponse: Player {} ({}) tried to bind himself/teleport to graveyard without a pending bind!",
1735 return;
1736 }
1737
1738 if (accept)
1740 else
1742
1743 _player->SetPendingBind(0, 0);
1744}
uint32 GetPendingBind() const
Definition: Player.h:2422
bool HasPendingBind() const
Definition: Player.h:2421
void RepopAtGraveyard()
Definition: Player.cpp:4906
void SetPendingBind(uint32 instanceId, uint32 bindTimer)
Definition: Player.h:2420
void BindToInstance()
Definition: PlayerStorage.cpp:6509
bool IsLfgRandomInstance() const
Definition: Group.h:314

References _player, Player::BindToInstance(), Player::GetGroup(), Object::GetGUID(), WorldObject::GetInstanceId(), WorldObject::GetName(), Player::GetPendingBind(), Player::HasPendingBind(), Group::isLFGGroup(), Group::IsLfgRandomInstance(), LOG_DEBUG, Player::RepopAtGraveyard(), Player::SetPendingBind(), and ObjectGuid::ToString().

Referenced by OpcodeTable::Initialize().

◆ HandleItemNameQueryOpcode()

void WorldSession::HandleItemNameQueryOpcode ( WorldPacket recvPacket)
1245{
1246 uint32 itemid;
1247 recvData >> itemid;
1248 recvData.read_skip<uint64>(); // guid
1249
1250 LOG_DEBUG("network", "WORLD: CMSG_ITEM_NAME_QUERY {}", itemid);
1251 ItemSetNameEntry const* pName = sObjectMgr->GetItemSetNameEntry(itemid);
1252 if (pName)
1253 {
1254 std::string Name = pName->name;
1256 if (loc_idx >= 0)
1257 if (ItemSetNameLocale const* isnl = sObjectMgr->GetItemSetNameLocale(itemid))
1258 ObjectMgr::GetLocaleString(isnl->Name, loc_idx, Name);
1259
1260 WorldPacket data(SMSG_ITEM_NAME_QUERY_RESPONSE, (4 + Name.size() + 1 + 4));
1261 data << uint32(itemid);
1262 data << Name;
1263 data << uint32(pName->InventoryType);
1264 SendPacket(&data);
1265 }
1266}
@ SMSG_ITEM_NAME_QUERY_RESPONSE
Definition: Opcodes.h:739
Definition: ItemTemplate.h:844
uint32 InventoryType
Definition: ItemTemplate.h:846
std::string name
Definition: ItemTemplate.h:845
Definition: ItemTemplate.h:850

References ObjectMgr::GetLocaleString(), GetSessionDbLocaleIndex(), ItemSetNameEntry::InventoryType, LOG_DEBUG, ItemSetNameEntry::name, ByteBuffer::read_skip(), SendPacket(), SMSG_ITEM_NAME_QUERY_RESPONSE, and sObjectMgr.

Referenced by OpcodeTable::Initialize().

◆ HandleItemQuerySingleOpcode()

void WorldSession::HandleItemQuerySingleOpcode ( WorldPacket recvPacket)
538{
539 //LOG_DEBUG("network.opcode", "WORLD: CMSG_ITEM_QUERY_SINGLE");
540 uint32 item;
541 recvData >> item;
542
543 LOG_DEBUG("network.opcode", "STORAGE: Item Query = {}", item);
544
545 ItemTemplate const* pProto = sObjectMgr->GetItemTemplate(item);
546 if (pProto)
547 {
548 std::string Name = pProto->Name1;
549 std::string Description = pProto->Description;
550
551 int loc_idx = GetSessionDbLocaleIndex();
552 if (loc_idx >= 0)
553 {
554 if (ItemLocale const* il = sObjectMgr->GetItemLocale(pProto->ItemId))
555 {
556 ObjectMgr::GetLocaleString(il->Name, loc_idx, Name);
557 ObjectMgr::GetLocaleString(il->Description, loc_idx, Description);
558 }
559 }
560 // guess size
562 queryData << pProto->ItemId;
563 queryData << pProto->Class;
564 queryData << pProto->SubClass;
565 queryData << pProto->SoundOverrideSubclass;
566 queryData << Name;
567 queryData << uint8(0x00); //pProto->Name2; // blizz not send name there, just uint8(0x00); <-- \0 = empty string = empty name...
568 queryData << uint8(0x00); //pProto->Name3; // blizz not send name there, just uint8(0x00);
569 queryData << uint8(0x00); //pProto->Name4; // blizz not send name there, just uint8(0x00);
570 queryData << pProto->DisplayInfoID;
571 queryData << pProto->Quality;
572 queryData << pProto->Flags;
573 queryData << pProto->Flags2;
574 queryData << pProto->BuyPrice;
575 queryData << pProto->SellPrice;
576 queryData << pProto->InventoryType;
577 queryData << pProto->AllowableClass;
578 queryData << pProto->AllowableRace;
579 queryData << pProto->ItemLevel;
580 queryData << pProto->RequiredLevel;
581 queryData << pProto->RequiredSkill;
582 queryData << pProto->RequiredSkillRank;
583 queryData << pProto->RequiredSpell;
584 queryData << pProto->RequiredHonorRank;
585 queryData << pProto->RequiredCityRank;
586 queryData << pProto->RequiredReputationFaction;
587 queryData << pProto->RequiredReputationRank;
588 queryData << int32(pProto->MaxCount);
589 queryData << int32(pProto->Stackable);
590 queryData << pProto->ContainerSlots;
591 queryData << pProto->StatsCount; // item stats count
592 for (uint32 i = 0; i < pProto->StatsCount; ++i)
593 {
594 queryData << pProto->ItemStat[i].ItemStatType;
595 queryData << pProto->ItemStat[i].ItemStatValue;
596 }
597 queryData << pProto->ScalingStatDistribution; // scaling stats distribution
598 queryData << pProto->ScalingStatValue; // some kind of flags used to determine stat values column
599 for (int i = 0; i < MAX_ITEM_PROTO_DAMAGES; ++i)
600 {
601 queryData << pProto->Damage[i].DamageMin;
602 queryData << pProto->Damage[i].DamageMax;
603 queryData << pProto->Damage[i].DamageType;
604 }
605
606 // resistances (7)
607 queryData << pProto->Armor;
608 queryData << pProto->HolyRes;
609 queryData << pProto->FireRes;
610 queryData << pProto->NatureRes;
611 queryData << pProto->FrostRes;
612 queryData << pProto->ShadowRes;
613 queryData << pProto->ArcaneRes;
614
615 queryData << pProto->Delay;
616 queryData << pProto->AmmoType;
617 queryData << pProto->RangedModRange;
618
619 for (int s = 0; s < MAX_ITEM_PROTO_SPELLS; ++s)
620 {
621 // send DBC data for cooldowns in same way as it used in Spell::SendSpellCooldown
622 // use `item_template` or if not set then only use spell cooldowns
623 SpellInfo const* spell = sSpellMgr->GetSpellInfo(pProto->Spells[s].SpellId);
624 if (spell)
625 {
626 bool db_data = pProto->Spells[s].SpellCooldown >= 0 || pProto->Spells[s].SpellCategoryCooldown >= 0;
627
628 queryData << pProto->Spells[s].SpellId;
629 queryData << pProto->Spells[s].SpellTrigger;
630 queryData << int32(pProto->Spells[s].SpellCharges);
631
632 if (db_data)
633 {
634 queryData << uint32(pProto->Spells[s].SpellCooldown);
635 queryData << uint32(pProto->Spells[s].SpellCategory);
636 queryData << uint32(pProto->Spells[s].SpellCategoryCooldown);
637 }
638 else
639 {
640 queryData << uint32(spell->RecoveryTime);
641 queryData << uint32(spell->GetCategory());
642 queryData << uint32(spell->CategoryRecoveryTime);
643 }
644 }
645 else
646 {
647 queryData << uint32(0);
648 queryData << uint32(0);
649 queryData << uint32(0);
650 queryData << uint32(-1);
651 queryData << uint32(0);
652 queryData << uint32(-1);
653 }
654 }
655 queryData << pProto->Bonding;
656 queryData << Description;
657 queryData << pProto->PageText;
658 queryData << pProto->LanguageID;
659 queryData << pProto->PageMaterial;
660 queryData << pProto->StartQuest;
661 queryData << pProto->LockID;
662 queryData << int32(pProto->Material);
663 queryData << pProto->Sheath;
664 queryData << pProto->RandomProperty;
665 queryData << pProto->RandomSuffix;
666 queryData << pProto->Block;
667 queryData << pProto->ItemSet;
668 queryData << pProto->MaxDurability;
669 queryData << pProto->Area;
670 queryData << pProto->Map; // Added in 1.12.x & 2.0.1 client branch
671 queryData << pProto->BagFamily;
672 queryData << pProto->TotemCategory;
673 for (int s = 0; s < MAX_ITEM_PROTO_SOCKETS; ++s)
674 {
675 queryData << pProto->Socket[s].Color;
676 queryData << pProto->Socket[s].Content;
677 }
678 queryData << pProto->socketBonus;
679 queryData << pProto->GemProperties;
680 queryData << pProto->RequiredDisenchantSkill;
681 queryData << pProto->ArmorDamageModifier;
682 queryData << pProto->Duration; // added in 2.4.2.8209, duration (seconds)
683 queryData << pProto->ItemLimitCategory; // WotLK, ItemLimitCategory
684 queryData << pProto->HolidayId; // Holiday.dbc?
685 SendPacket(&queryData);
686 }
687 else
688 {
689 LOG_DEBUG("network", "WORLD: CMSG_ITEM_QUERY_SINGLE - NO item INFO! (ENTRY: {})", item);
691 queryData << uint32(item | 0x80000000);
692 SendPacket(&queryData);
693 }
694}
#define MAX_ITEM_PROTO_SOCKETS
Definition: ItemTemplate.h:614
#define MAX_ITEM_PROTO_DAMAGES
Definition: ItemTemplate.h:613
#define MAX_ITEM_PROTO_SPELLS
Definition: ItemTemplate.h:615
@ SMSG_ITEM_QUERY_SINGLE_RESPONSE
Definition: Opcodes.h:118
float DamageMin
Definition: ItemTemplate.h:579
uint32 DamageType
Definition: ItemTemplate.h:581
float DamageMax
Definition: ItemTemplate.h:580
int32 ItemStatValue
Definition: ItemTemplate.h:587
uint32 ItemStatType
Definition: ItemTemplate.h:586
int32 SpellCharges
Definition: ItemTemplate.h:593
uint32 SpellTrigger
Definition: ItemTemplate.h:592
int32 SpellCategoryCooldown
Definition: ItemTemplate.h:597
int32 SpellCooldown
Definition: ItemTemplate.h:595
uint32 SpellCategory
Definition: ItemTemplate.h:596
int32 SpellId
Definition: ItemTemplate.h:591
uint32 Content
Definition: ItemTemplate.h:603
uint32 Color
Definition: ItemTemplate.h:602
int32 RandomProperty
Definition: ItemTemplate.h:672
int32 FrostRes
Definition: ItemTemplate.h:656
ItemFlags2 Flags2
Definition: ItemTemplate.h:628
uint32 Map
Definition: ItemTemplate.h:678
uint32 Block
Definition: ItemTemplate.h:674
uint32 Quality
Definition: ItemTemplate.h:626
uint32 ItemLevel
Definition: ItemTemplate.h:635
int32 ArcaneRes
Definition: ItemTemplate.h:658
uint32 RequiredCityRank
Definition: ItemTemplate.h:641
uint32 RequiredSkill
Definition: ItemTemplate.h:637
int32 ShadowRes
Definition: ItemTemplate.h:657
uint32 RequiredSpell
Definition: ItemTemplate.h:639
int32 MaxCount
Definition: ItemTemplate.h:644
uint32 ScalingStatValue
Definition: ItemTemplate.h:650
std::string Description
Definition: ItemTemplate.h:664
uint32 AllowableClass
Definition: ItemTemplate.h:633
uint32 RequiredSkillRank
Definition: ItemTemplate.h:638
_Damage Damage[MAX_ITEM_PROTO_DAMAGES]
Definition: ItemTemplate.h:651
uint32 RequiredHonorRank
Definition: ItemTemplate.h:640
int32 HolyRes
Definition: ItemTemplate.h:653
float RangedModRange
Definition: ItemTemplate.h:661
uint32 Sheath
Definition: ItemTemplate.h:671
float ArmorDamageModifier
Definition: ItemTemplate.h:685
int32 Material
Definition: ItemTemplate.h:670
_Spell Spells[MAX_ITEM_PROTO_SPELLS]
Definition: ItemTemplate.h:662
uint32 Area
Definition: ItemTemplate.h:677
int32 BuyPrice
Definition: ItemTemplate.h:630
uint32 socketBonus
Definition: ItemTemplate.h:682
uint32 RequiredDisenchantSkill
Definition: ItemTemplate.h:684
uint32 TotemCategory
Definition: ItemTemplate.h:680
uint32 PageMaterial
Definition: ItemTemplate.h:667
uint32 RequiredLevel
Definition: ItemTemplate.h:636
uint32 LockID
Definition: ItemTemplate.h:669
uint32 ItemSet
Definition: ItemTemplate.h:675
uint32 HolidayId
Definition: ItemTemplate.h:688
uint32 GemProperties
Definition: ItemTemplate.h:683
uint32 RequiredReputationRank
Definition: ItemTemplate.h:643
uint32 ContainerSlots
Definition: ItemTemplate.h:646
uint32 DisplayInfoID
Definition: ItemTemplate.h:625
uint32 AllowableRace
Definition: ItemTemplate.h:634
uint32 RequiredReputationFaction
Definition: ItemTemplate.h:642
uint32 Class
Definition: ItemTemplate.h:621
uint32 ItemLimitCategory
Definition: ItemTemplate.h:687
uint32 PageText
Definition: ItemTemplate.h:665
uint32 ScalingStatDistribution
Definition: ItemTemplate.h:649
int32 NatureRes
Definition: ItemTemplate.h:655
_ItemStat ItemStat[MAX_ITEM_PROTO_STATS]
Definition: ItemTemplate.h:648
uint32 MaxDurability
Definition: ItemTemplate.h:676
uint32 BagFamily
Definition: ItemTemplate.h:679
uint32 InventoryType
Definition: ItemTemplate.h:632
uint32 LanguageID
Definition: ItemTemplate.h:666
uint32 AmmoType
Definition: ItemTemplate.h:660
uint32 Delay
Definition: ItemTemplate.h:659
int32 RandomSuffix
Definition: ItemTemplate.h:673
uint32 Duration
Definition: ItemTemplate.h:686
uint32 SubClass
Definition: ItemTemplate.h:622
uint32 Armor
Definition: ItemTemplate.h:652
int32 Stackable
Definition: ItemTemplate.h:645
uint32 StartQuest
Definition: ItemTemplate.h:668
int32 SoundOverrideSubclass
Definition: ItemTemplate.h:623
_Socket Socket[MAX_ITEM_PROTO_SOCKETS]
Definition: ItemTemplate.h:681
uint32 StatsCount
Definition: ItemTemplate.h:647
int32 FireRes
Definition: ItemTemplate.h:654
uint32 Bonding
Definition: ItemTemplate.h:663
uint32 SellPrice
Definition: ItemTemplate.h:631
Definition: ItemTemplate.h:838
uint32 GetCategory() const
Definition: SpellInfo.cpp:870
uint32 RecoveryTime
Definition: SpellInfo.h:348
uint32 CategoryRecoveryTime
Definition: SpellInfo.h:349

References ItemTemplate::AllowableClass, ItemTemplate::AllowableRace, ItemTemplate::AmmoType, ItemTemplate::ArcaneRes, ItemTemplate::Area, ItemTemplate::Armor, ItemTemplate::ArmorDamageModifier, ItemTemplate::BagFamily, ItemTemplate::Block, ItemTemplate::Bonding, ItemTemplate::BuyPrice, SpellInfo::CategoryRecoveryTime, ItemTemplate::Class, _Socket::Color, ItemTemplate::ContainerSlots, _Socket::Content, ItemTemplate::Damage, _Damage::DamageMax, _Damage::DamageMin, _Damage::DamageType, ItemTemplate::Delay, ItemTemplate::Description, ItemTemplate::DisplayInfoID, ItemTemplate::Duration, ItemTemplate::FireRes, ItemTemplate::Flags, ItemTemplate::Flags2, ItemTemplate::FrostRes, ItemTemplate::GemProperties, SpellInfo::GetCategory(), ObjectMgr::GetLocaleString(), GetSessionDbLocaleIndex(), ItemTemplate::HolidayId, ItemTemplate::HolyRes, ItemTemplate::InventoryType, ItemTemplate::ItemId, ItemTemplate::ItemLevel, ItemTemplate::ItemLimitCategory, ItemTemplate::ItemSet, ItemTemplate::ItemStat, _ItemStat::ItemStatType, _ItemStat::ItemStatValue, ItemTemplate::LanguageID, ItemTemplate::LockID, LOG_DEBUG, ItemTemplate::Map, ItemTemplate::Material, MAX_ITEM_PROTO_DAMAGES, MAX_ITEM_PROTO_SOCKETS, MAX_ITEM_PROTO_SPELLS, ItemTemplate::MaxCount, ItemTemplate::MaxDurability, ItemTemplate::Name1, ItemTemplate::NatureRes, ItemTemplate::PageMaterial, ItemTemplate::PageText, ItemTemplate::Quality, ItemTemplate::RandomProperty, ItemTemplate::RandomSuffix, ItemTemplate::RangedModRange, SpellInfo::RecoveryTime, ItemTemplate::RequiredCityRank, ItemTemplate::RequiredDisenchantSkill, ItemTemplate::RequiredHonorRank, ItemTemplate::RequiredLevel, ItemTemplate::RequiredReputationFaction, ItemTemplate::RequiredReputationRank, ItemTemplate::RequiredSkill, ItemTemplate::RequiredSkillRank, ItemTemplate::RequiredSpell, ItemTemplate::ScalingStatDistribution, ItemTemplate::ScalingStatValue, ItemTemplate::SellPrice, SendPacket(), ItemTemplate::ShadowRes, ItemTemplate::Sheath, SMSG_ITEM_QUERY_SINGLE_RESPONSE, sObjectMgr, ItemTemplate::Socket, ItemTemplate::socketBonus, ItemTemplate::SoundOverrideSubclass, _Spell::SpellCategory, _Spell::SpellCategoryCooldown, _Spell::SpellCharges, _Spell::SpellCooldown, _Spell::SpellId, ItemTemplate::Spells, _Spell::SpellTrigger, sSpellMgr, ItemTemplate::Stackable, ItemTemplate::StartQuest, ItemTemplate::StatsCount, ItemTemplate::SubClass, and ItemTemplate::TotemCategory.

Referenced by OpcodeTable::Initialize().

◆ HandleItemRefund()

void WorldSession::HandleItemRefund ( WorldPacket recvData)
1641{
1642 LOG_DEBUG("network", "WORLD: CMSG_ITEM_REFUND");
1643 ObjectGuid guid;
1644 recvData >> guid; // item guid
1645
1646 Item* item = _player->GetItemByGuid(guid);
1647 if (!item)
1648 {
1649 LOG_DEBUG("network", "Item refund: item not found!");
1650 return;
1651 }
1652
1653 // Don't try to refund item currently being disenchanted
1654 if (_player->GetLootGUID() == guid)
1655 return;
1656
1657 GetPlayer()->RefundItem(item);
1658}
void RefundItem(Item *item)
Definition: Player.cpp:15595

References _player, Player::GetItemByGuid(), Player::GetLootGUID(), GetPlayer(), LOG_DEBUG, and Player::RefundItem().

Referenced by OpcodeTable::Initialize().

◆ HandleItemRefundInfoRequest()

void WorldSession::HandleItemRefundInfoRequest ( WorldPacket recvData)
1624{
1625 LOG_DEBUG("network", "WORLD: CMSG_ITEM_REFUND_INFO");
1626
1627 ObjectGuid guid;
1628 recvData >> guid; // item guid
1629
1630 Item* item = _player->GetItemByGuid(guid);
1631 if (!item)
1632 {
1633 LOG_DEBUG("network", "Item refund: item not found!");
1634 return;
1635 }
1636
1637 GetPlayer()->SendRefundInfo(item);
1638}
void SendRefundInfo(Item *item)
Definition: Player.cpp:15524

References _player, Player::GetItemByGuid(), GetPlayer(), LOG_DEBUG, and Player::SendRefundInfo().

Referenced by OpcodeTable::Initialize().

◆ HandleItemTextQuery()

void WorldSession::HandleItemTextQuery ( WorldPacket recvData)

Handles the packet sent by the client when requesting information about item text.

This function is called when player clicks on item which has some flag set

1666{
1667 ObjectGuid itemGuid;
1668 recvData >> itemGuid;
1669
1670 LOG_DEBUG("network", "CMSG_ITEM_TEXT_QUERY item: {}", itemGuid.ToString());
1671
1672 WorldPacket data(SMSG_ITEM_TEXT_QUERY_RESPONSE, 50); // guess size
1673
1674 if (Item* item = _player->GetItemByGuid(itemGuid))
1675 {
1676 data << uint8(0); // has text
1677 data << itemGuid; // item guid
1678 data << item->GetText();
1679 }
1680 else
1681 {
1682 data << uint8(1); // no text
1683 }
1684
1685 SendPacket(&data);
1686}
@ SMSG_ITEM_TEXT_QUERY_RESPONSE
Definition: Opcodes.h:610

References _player, Player::GetItemByGuid(), LOG_DEBUG, SendPacket(), SMSG_ITEM_TEXT_QUERY_RESPONSE, and ObjectGuid::ToString().

Referenced by OpcodeTable::Initialize().

◆ HandleJoinChannel()

void WorldSession::HandleJoinChannel ( WorldPacket recvPacket)
24{
25 uint32 channelId;
26 uint8 unknown1, unknown2;
27 std::string channelName, password;
28
29 recvPacket >> channelId >> unknown1 >> unknown2 >> channelName >> password;
30
31 LOG_DEBUG("chat.system", "CMSG_JOIN_CHANNEL {} Channel: {}, unk1: {}, unk2: {}, channel: {}, password: {}", GetPlayerInfo(), channelId, unknown1, unknown2, channelName, password);
32 if (channelId)
33 {
34 ChatChannelsEntry const* channel = sChatChannelsStore.LookupEntry(channelId);
35 if (!channel)
36 return;
37
38 AreaTableEntry const* zone = sAreaTableStore.LookupEntry(GetPlayer()->GetZoneId());
39 if (!zone || !GetPlayer()->CanJoinConstantChannelInZone(channel, zone))
40 return;
41 }
42
43 if (channelName.empty())
44 return;
45
46 if (isdigit(channelName[0]))
47 return;
48
49 if (channelName.size() >= 100 || !DisallowHyperlinksAndMaybeKick(channelName))
50 {
51 return;
52 }
53
55 {
56 if (Channel* channel = cMgr->GetJoinChannel(channelName, channelId))
57 channel->JoinChannel(GetPlayer(), password);
58 }
59}
DBCStorage< ChatChannelsEntry > sChatChannelsStore(ChatChannelsEntryfmt)
bool DisallowHyperlinksAndMaybeKick(std::string_view str)
Definition: WorldSession.cpp:779
Definition: DBCStructure.h:642

References DisallowHyperlinksAndMaybeKick(), ChannelMgr::forTeam(), GetPlayer(), GetPlayerInfo(), GetTeamId(), LOG_DEBUG, sAreaTableStore, and sChatChannelsStore.

Referenced by OpcodeTable::Initialize().

◆ HandleLearnPreviewTalents()

void WorldSession::HandleLearnPreviewTalents ( WorldPacket recvPacket)
35{
36 LOG_DEBUG("network", "CMSG_LEARN_PREVIEW_TALENTS");
37
38 uint32 talentsCount;
39 recvPacket >> talentsCount;
40
41 uint32 talentId, talentRank;
42
43 // Client has max 44 talents for tree for 3 trees, rounded up : 150
44 uint32 const MaxTalentsCount = 150;
45
46 for (uint32 i = 0; i < talentsCount && i < MaxTalentsCount; ++i)
47 {
48 recvPacket >> talentId >> talentRank;
49
50 _player->LearnTalent(talentId, talentRank);
51 }
52
54
55 recvPacket.rfinish();
56}
void SendTalentsInfoData(bool pet)
Definition: Player.cpp:14424
void LearnTalent(uint32 talentId, uint32 talentRank, bool command=false)
Definition: Player.cpp:13943

References _player, Player::LearnTalent(), LOG_DEBUG, ByteBuffer::rfinish(), and Player::SendTalentsInfoData().

Referenced by OpcodeTable::Initialize().

◆ HandleLearnPreviewTalentsPet()

void WorldSession::HandleLearnPreviewTalentsPet ( WorldPacket recvPacket)
1119{
1120 LOG_DEBUG("network", "CMSG_LEARN_PREVIEW_TALENTS_PET");
1121
1122 ObjectGuid guid;
1123 recvData >> guid;
1124
1125 uint32 talentsCount;
1126 recvData >> talentsCount;
1127
1128 uint32 talentId, talentRank;
1129
1130 // Client has max 24 talents, rounded up : 30
1131 uint32 const MaxTalentsCount = 30;
1132
1133 for (uint32 i = 0; i < talentsCount && i < MaxTalentsCount; ++i)
1134 {
1135 recvData >> talentId >> talentRank;
1136
1137 _player->LearnPetTalent(guid, talentId, talentRank);
1138 }
1139
1141
1142 recvData.rfinish();
1143}
void LearnPetTalent(ObjectGuid petGuid, uint32 talentId, uint32 talentRank)
Definition: Player.cpp:14079

References _player, Player::LearnPetTalent(), LOG_DEBUG, ByteBuffer::rfinish(), and Player::SendTalentsInfoData().

Referenced by OpcodeTable::Initialize().

◆ HandleLearnTalentOpcode()

void WorldSession::HandleLearnTalentOpcode ( WorldPacket recvPacket)
26{
27 uint32 talent_id, requested_rank;
28 recvData >> talent_id >> requested_rank;
29
30 _player->LearnTalent(talent_id, requested_rank);
32}

References _player, Player::LearnTalent(), and Player::SendTalentsInfoData().

Referenced by OpcodeTable::Initialize().

◆ HandleLeaveChannel()

void WorldSession::HandleLeaveChannel ( WorldPacket recvPacket)
62{
63 uint32 unk;
64 std::string channelName;
65 recvPacket >> unk >> channelName;
66
67 LOG_DEBUG("chat.system", "CMSG_LEAVE_CHANNEL {} Channel: {}, unk1: {}",
68 GetPlayerInfo(), channelName, unk);
69 if (channelName.empty())
70 return;
71
73 {
74 if (Channel* channel = cMgr->GetChannel(channelName, GetPlayer()))
75 channel->LeaveChannel(GetPlayer(), true);
76 }
77}

References ChannelMgr::forTeam(), GetPlayer(), GetPlayerInfo(), GetTeamId(), and LOG_DEBUG.

Referenced by OpcodeTable::Initialize().

◆ HandleLfgGetStatus()

void WorldSession::HandleLfgGetStatus ( WorldPacket recvData)
276{
277 LOG_DEBUG("lfg", "CMSG_LFG_GET_STATUS {}", GetPlayerInfo());
278
279 ObjectGuid guid = GetPlayer()->GetGUID();
280 lfg::LfgUpdateData updateData = sLFGMgr->GetLfgStatus(guid);
281
282 if (GetPlayer()->GetGroup())
283 {
284 SendLfgUpdateParty(updateData);
285 updateData.dungeons.clear();
286 SendLfgUpdatePlayer(updateData);
287 }
288 else
289 {
290 SendLfgUpdatePlayer(updateData);
291 updateData.dungeons.clear();
292 SendLfgUpdateParty(updateData);
293 }
294}
Definition: LFGMgr.h:290
LfgDungeonSet dungeons
Definition: LFGMgr.h:299
void SendLfgUpdatePlayer(lfg::LfgUpdateData const &updateData)
Definition: LFGHandler.cpp:296
void SendLfgUpdateParty(lfg::LfgUpdateData const &updateData)
Definition: LFGHandler.cpp:333

References lfg::LfgUpdateData::dungeons, Object::GetGUID(), GetPlayer(), GetPlayerInfo(), LOG_DEBUG, SendLfgUpdateParty(), SendLfgUpdatePlayer(), and sLFGMgr.

Referenced by OpcodeTable::Initialize().

◆ HandleLfgJoinOpcode()

void WorldSession::HandleLfgJoinOpcode ( WorldPackets::LFG::LFGJoin lfgJoin)
50{
52 (GetPlayer()->GetGroup() && GetPlayer()->GetGroup()->GetLeaderGUID() != GetPlayer()->GetGUID() &&
53 (GetPlayer()->GetGroup()->GetMembersCount() == MAXGROUPSIZE || !GetPlayer()->GetGroup()->isLFGGroup())))
54 return;
55
56 if (packet.Slots.empty())
57 {
58 LOG_DEBUG("lfg", "CMSG_LFG_JOIN {} no dungeons selected", GetPlayerInfo());
59 return;
60 }
61
62 lfg::LfgDungeonSet newDungeons;
63 for (uint32 slot : packet.Slots)
64 {
65 uint32 dungeon = slot & 0x00FFFFFF; // remove the type from the dungeon entry
66 if (sLFGDungeonStore.LookupEntry(dungeon))
67 newDungeons.insert(dungeon);
68 }
69
70 LOG_DEBUG("network", "CMSG_LFG_JOIN [{}] roles: {}, Dungeons: {}, Comment: {}",
71 GetPlayerInfo(), packet.Roles, newDungeons.size(), packet.Comment);
72
73 sLFGMgr->JoinLfg(GetPlayer(), uint8(packet.Roles), newDungeons, packet.Comment);
74}
#define MAXGROUPSIZE
Definition: Group.h:43
DBCStorage< LFGDungeonEntry > sLFGDungeonStore(LFGDungeonEntryfmt)
@ LFG_OPTION_ENABLE_SEASONAL_BOSSES
Definition: LFGMgr.h:43
@ LFG_OPTION_ENABLE_DUNGEON_FINDER
Definition: LFGMgr.h:41
@ LFG_OPTION_ENABLE_RAID_BROWSER
Definition: LFGMgr.h:42
std::set< uint32 > LfgDungeonSet
Definition: LFG.h:109

References WorldPackets::LFG::LFGJoin::Comment, WorldPackets::Array< T, N >::empty(), GetPlayer(), GetPlayerInfo(), lfg::LFG_OPTION_ENABLE_DUNGEON_FINDER, lfg::LFG_OPTION_ENABLE_RAID_BROWSER, lfg::LFG_OPTION_ENABLE_SEASONAL_BOSSES, LOG_DEBUG, MAXGROUPSIZE, WorldPackets::LFG::LFGJoin::Roles, sLFGDungeonStore, sLFGMgr, and WorldPackets::LFG::LFGJoin::Slots.

Referenced by OpcodeTable::Initialize().

◆ HandleLfgLeaveOpcode()

void WorldSession::HandleLfgLeaveOpcode ( WorldPackets::LFG::LFGLeave lfgleave)
77{
78 Group* group = GetPlayer()->GetGroup();
79 ObjectGuid guid = GetPlayer()->GetGUID();
80 ObjectGuid gguid = group ? group->GetGUID() : guid;
81
82 LOG_DEBUG("network", "CMSG_LFG_LEAVE [{}] in group: {}", guid.ToString(), group ? 1 : 0);
83
84 // Check cheating - only leader can leave the queue
85 if (!group || group->GetLeaderGUID() == guid)
86 {
87 sLFGMgr->LeaveLfg(sLFGMgr->GetState(guid) == lfg::LFG_STATE_RAIDBROWSER ? guid : gguid);
88 sLFGMgr->LeaveAllLfgQueues(guid, true, group ? group->GetGUID() : ObjectGuid::Empty);
89 }
90}
@ LFG_STATE_RAIDBROWSER
Definition: LFG.h:78
ObjectGuid GetGUID() const
Definition: Group.cpp:2306

References ObjectGuid::Empty, Player::GetGroup(), Group::GetGUID(), Object::GetGUID(), Group::GetLeaderGUID(), GetPlayer(), lfg::LFG_STATE_RAIDBROWSER, LOG_DEBUG, sLFGMgr, and ObjectGuid::ToString().

Referenced by OpcodeTable::Initialize().

◆ HandleLfgPartyLockInfoRequestOpcode()

void WorldSession::HandleLfgPartyLockInfoRequestOpcode ( WorldPacket recvData)
225{
226 ObjectGuid guid = GetPlayer()->GetGUID();
227 LOG_DEBUG("network", "CMSG_LFG_PARTY_LOCK_INFO_REQUEST [{}]", guid.ToString());
228
229 Group* group = GetPlayer()->GetGroup();
230 if (!group)
231 return;
232
233 // Get the locked dungeons of the other party members
234 lfg::LfgLockPartyMap lockMap;
235 for (GroupReference* itr = group->GetFirstMember(); itr != nullptr; itr = itr->next())
236 {
237 Player* plrg = itr->GetSource();
238 if (!plrg)
239 continue;
240
241 ObjectGuid pguid = plrg->GetGUID();
242 if (pguid == guid)
243 continue;
244
245 sLFGMgr->InitializeLockedDungeons(plrg, group); // pussywizard
246 lockMap[pguid] = sLFGMgr->GetLockedDungeons(pguid);
247 }
248
249 uint32 size = 0;
250 for (lfg::LfgLockPartyMap::const_iterator it = lockMap.begin(); it != lockMap.end(); ++it)
251 size += 8 + 4 + uint32(it->second.size()) * (4 + 4);
252
253 LOG_DEBUG("network", "SMSG_LFG_PARTY_INFO [{}]", guid.ToString());
254 WorldPacket data(SMSG_LFG_PARTY_INFO, 1 + size);
255 BuildPartyLockDungeonBlock(data, lockMap);
256 SendPacket(&data);
257}
void BuildPartyLockDungeonBlock(WorldPacket &data, const lfg::LfgLockPartyMap &lockMap)
Definition: LFGHandler.cpp:39
@ SMSG_LFG_PARTY_INFO
Definition: Opcodes.h:912
std::map< ObjectGuid, LfgLockMap > LfgLockPartyMap
Definition: LFG.h:111

References BuildPartyLockDungeonBlock(), Group::GetFirstMember(), Player::GetGroup(), Object::GetGUID(), GetPlayer(), LOG_DEBUG, GroupReference::next(), SendPacket(), sLFGMgr, SMSG_LFG_PARTY_INFO, and ObjectGuid::ToString().

Referenced by OpcodeTable::Initialize().

◆ HandleLfgPlayerLockInfoRequestOpcode()

void WorldSession::HandleLfgPlayerLockInfoRequestOpcode ( WorldPacket recvData)
150{
151 ObjectGuid guid = GetPlayer()->GetGUID();
152 LOG_DEBUG("network", "CMSG_LFG_PLAYER_LOCK_INFO_REQUEST [{}]", guid.ToString());
153
154 // Get Random dungeons that can be done at a certain level and expansion
155 uint8 level = GetPlayer()->GetLevel();
156 lfg::LfgDungeonSet const& randomDungeons =
157 sLFGMgr->GetRandomAndSeasonalDungeons(level, GetPlayer()->GetSession()->Expansion());
158
159 // Get player locked Dungeons
160 sLFGMgr->InitializeLockedDungeons(GetPlayer(), GetPlayer()->GetGroup()); // pussywizard
161 lfg::LfgLockMap const& lock = sLFGMgr->GetLockedDungeons(guid);
162 uint32 rsize = uint32(randomDungeons.size());
163 uint32 lsize = uint32(lock.size());
164
165 LOG_DEBUG("network", "SMSG_LFG_PLAYER_INFO [{}]", guid.ToString());
166 WorldPacket data(SMSG_LFG_PLAYER_INFO, 1 + rsize * (4 + 1 + 4 + 4 + 4 + 4 + 1 + 4 + 4 + 4) + 4 + lsize * (1 + 4 + 4 + 4 + 4 + 1 + 4 + 4 + 4));
167
168 data << uint8(randomDungeons.size()); // Random Dungeon count
169 for (lfg::LfgDungeonSet::const_iterator it = randomDungeons.begin(); it != randomDungeons.end(); ++it)
170 {
171 data << uint32(*it); // Dungeon Entry (id + type)
172 lfg::LfgReward const* reward = sLFGMgr->GetRandomDungeonReward(*it, level);
173 Quest const* quest = nullptr;
174 bool done = false;
175 if (reward)
176 {
177 quest = sObjectMgr->GetQuestTemplate(reward->firstQuest);
178 if (quest)
179 {
180 done = !GetPlayer()->CanRewardQuest(quest, false);
181 if (done)
182 quest = sObjectMgr->GetQuestTemplate(reward->otherQuest);
183 }
184 }
185
186 if (quest)
187 {
188 uint8 playerLevel = GetPlayer() ? GetPlayer()->GetLevel() : 0;
189 data << uint8(done);
190 data << uint32(quest->GetRewOrReqMoney(playerLevel));
191 if (!GetPlayer()->IsMaxLevel())
192 data << uint32(quest->XPValue(playerLevel));
193 else
194 data << uint32(0);
195 data << uint32(0);
196 data << uint32(0);
197 data << uint8(quest->GetRewItemsCount());
198 if (quest->GetRewItemsCount())
199 {
200 for (uint8 i = 0; i < QUEST_REWARDS_COUNT; ++i)
201 if (uint32 itemId = quest->RewardItemId[i])
202 {
203 ItemTemplate const* item = sObjectMgr->GetItemTemplate(itemId);
204 data << uint32(itemId);
205 data << uint32(item ? item->DisplayInfoID : 0);
206 data << uint32(quest->RewardItemIdCount[i]);
207 }
208 }
209 }
210 else
211 {
212 data << uint8(0);
213 data << uint32(0);
214 data << uint32(0);
215 data << uint32(0);
216 data << uint32(0);
217 data << uint8(0);
218 }
219 }
220 BuildPlayerLockDungeonBlock(data, lock);
221 SendPacket(&data);
222}
#define QUEST_REWARDS_COUNT
Definition: QuestDef.h:39
void BuildPlayerLockDungeonBlock(WorldPacket &data, lfg::LfgLockMap const &lock)
Definition: LFGHandler.cpp:29
@ SMSG_LFG_PLAYER_INFO
Definition: Opcodes.h:909
std::map< uint32, uint32 > LfgLockMap
Definition: LFG.h:110
Definition: LFGMgr.h:335
uint32 firstQuest
Definition: LFGMgr.h:340
uint32 otherQuest
Definition: LFGMgr.h:341
bool CanRewardQuest(Quest const *quest, bool msg)
Definition: PlayerQuest.cpp:384
Definition: QuestDef.h:210
uint32 RewardItemIdCount[QUEST_REWARDS_COUNT]
Definition: QuestDef.h:309
uint32 GetRewItemsCount() const
Definition: QuestDef.h:321
uint32 XPValue(uint8 playerLevel=0) const
Definition: QuestDef.cpp:198
int32 GetRewOrReqMoney(uint8 playerLevel=0) const
Definition: QuestDef.cpp:238
uint32 RewardItemId[QUEST_REWARDS_COUNT]
Definition: QuestDef.h:308

References BuildPlayerLockDungeonBlock(), Player::CanRewardQuest(), ItemTemplate::DisplayInfoID, Expansion(), lfg::LfgReward::firstQuest, Object::GetGUID(), Unit::GetLevel(), GetPlayer(), Quest::GetRewItemsCount(), Quest::GetRewOrReqMoney(), LOG_DEBUG, lfg::LfgReward::otherQuest, QUEST_REWARDS_COUNT, Quest::RewardItemId, Quest::RewardItemIdCount, SendPacket(), sLFGMgr, SMSG_LFG_PLAYER_INFO, sObjectMgr, ObjectGuid::ToString(), and Quest::XPValue().

Referenced by OpcodeTable::Initialize().

◆ HandleLfgProposalResultOpcode()

void WorldSession::HandleLfgProposalResultOpcode ( WorldPacket recvData)
93{
94 uint32 proposalID; // Internal lfgGroupID
95 bool accept; // Accept to join?
96 recvData >> proposalID;
97 recvData >> accept;
98
99 LOG_DEBUG("network", "CMSG_LFG_PROPOSAL_RESULT [{}] proposal: {} accept: {}", GetPlayer()->GetGUID().ToString(), proposalID, accept ? 1 : 0);
100 sLFGMgr->UpdateProposal(proposalID, GetPlayer()->GetGUID(), accept);
101}

References GetPlayer(), LOG_DEBUG, and sLFGMgr.

Referenced by OpcodeTable::Initialize().

◆ HandleLfgSetBootVoteOpcode()

void WorldSession::HandleLfgSetBootVoteOpcode ( WorldPacket recvData)
131{
132 bool agree; // Agree to kick player
133 recvData >> agree;
134
135 ObjectGuid guid = GetPlayer()->GetGUID();
136 LOG_DEBUG("network", "CMSG_LFG_SET_BOOT_VOTE [{}] agree: {}", guid.ToString(), agree ? 1 : 0);
137 sLFGMgr->UpdateBoot(guid, agree);
138}

References Object::GetGUID(), GetPlayer(), LOG_DEBUG, sLFGMgr, and ObjectGuid::ToString().

Referenced by OpcodeTable::Initialize().

◆ HandleLfgSetCommentOpcode()

void WorldSession::HandleLfgSetCommentOpcode ( WorldPacket recvData)
120{
121 std::string comment;
122 recvData >> comment;
123 ObjectGuid guid = GetPlayer()->GetGUID();
124 LOG_DEBUG("network", "CMSG_LFG_SET_COMMENT [{}] comment: {}", guid.ToString(), comment);
125
126 sLFGMgr->SetComment(GetPlayer()->GetGUID(), comment);
127 sLFGMgr->LfrSetComment(GetPlayer(), comment);
128}

References Object::GetGUID(), GetPlayer(), LOG_DEBUG, sLFGMgr, and ObjectGuid::ToString().

Referenced by OpcodeTable::Initialize().

◆ HandleLfgSetRolesOpcode()

void WorldSession::HandleLfgSetRolesOpcode ( WorldPacket recvData)
104{
105 uint8 roles;
106 recvData >> roles; // Player Group Roles
107 ObjectGuid guid = GetPlayer()->GetGUID();
108 Group* group = GetPlayer()->GetGroup();
109 if (!group)
110 {
111 LOG_DEBUG("network", "CMSG_LFG_SET_ROLES [{}] Not in group", guid.ToString());
112 return;
113 }
114 ObjectGuid gguid = group->GetGUID();
115 LOG_DEBUG("network", "CMSG_LFG_SET_ROLES: Group [{}], Player [{}], Roles: {}", gguid.ToString(), guid.ToString(), roles);
116 sLFGMgr->UpdateRoleCheck(gguid, guid, roles);
117}

References Player::GetGroup(), Group::GetGUID(), Object::GetGUID(), GetPlayer(), LOG_DEBUG, sLFGMgr, and ObjectGuid::ToString().

Referenced by OpcodeTable::Initialize().

◆ HandleLfgTeleportOpcode()

void WorldSession::HandleLfgTeleportOpcode ( WorldPacket recvData)
141{
142 bool out;
143 recvData >> out;
144
145 LOG_DEBUG("network", "CMSG_LFG_TELEPORT [{}] out: {}", GetPlayer()->GetGUID().ToString(), out ? 1 : 0);
146 sLFGMgr->TeleportPlayer(GetPlayer(), out);
147}

References GetPlayer(), LOG_DEBUG, and sLFGMgr.

Referenced by OpcodeTable::Initialize().

◆ HandleLfrSearchJoinOpcode()

void WorldSession::HandleLfrSearchJoinOpcode ( WorldPacket recvData)
260{
261 uint32 dungeonId;
262 recvData >> dungeonId;
263 dungeonId = (dungeonId & 0x00FFFFFF); // remove the type from the dungeon entry
264 sLFGMgr->LfrSearchAdd(GetPlayer(), dungeonId);
265 sLFGMgr->SendRaidBrowserCachedList(GetPlayer(), dungeonId);
266}

References GetPlayer(), and sLFGMgr.

Referenced by OpcodeTable::Initialize().

◆ HandleLfrSearchLeaveOpcode()

void WorldSession::HandleLfrSearchLeaveOpcode ( WorldPacket recvData)
269{
270 uint32 dungeonId;
271 recvData >> dungeonId;
272 sLFGMgr->LfrSearchRemove(GetPlayer());
273}

References GetPlayer(), and sLFGMgr.

Referenced by OpcodeTable::Initialize().

◆ HandleListInventoryOpcode()

void WorldSession::HandleListInventoryOpcode ( WorldPacket recvPacket)
1023{
1024 ObjectGuid guid;
1025
1026 recvData >> guid;
1027
1028 if (!GetPlayer()->IsAlive())
1029 return;
1030
1031 LOG_DEBUG("network", "WORLD: Recvd CMSG_LIST_INVENTORY");
1032
1033 SendListInventory(guid);
1034}
void SendListInventory(ObjectGuid guid, uint32 vendorEntry=0)
Definition: ItemHandler.cpp:1036

References GetPlayer(), LOG_DEBUG, and SendListInventory().

Referenced by OpcodeTable::Initialize().

◆ HandleListStabledPetsOpcode()

void WorldSession::HandleListStabledPetsOpcode ( WorldPacket recvPacket)
460{
461 LOG_DEBUG("network", "WORLD: Recv MSG_LIST_STABLED_PETS");
462 ObjectGuid npcGUID;
463
464 recvData >> npcGUID;
465
466 if (!CheckStableMaster(npcGUID))
467 return;
468
469 // remove fake death
470 if (GetPlayer()->HasUnitState(UNIT_STATE_DIED))
472
473 // remove mounts this fix bug where getting pet from stable while mounted deletes pet.
474 if (GetPlayer()->IsMounted())
476
477 SendStablePet(npcGUID);
478}
void SendStablePet(ObjectGuid guid)
Definition: NPCHandler.cpp:480

References CheckStableMaster(), GetPlayer(), LOG_DEBUG, Unit::RemoveAurasByType(), SendStablePet(), SPELL_AURA_FEIGN_DEATH, SPELL_AURA_MOUNTED, and UNIT_STATE_DIED.

Referenced by OpcodeTable::Initialize().

◆ HandleLoadActionsSwitchSpec()

void WorldSession::HandleLoadActionsSwitchSpec ( PreparedQueryResult  result)
581{
582 if (!GetPlayer())
583 return;
584
585 if (result)
586 GetPlayer()->_LoadActions(result);
587
589}
void _LoadActions(PreparedQueryResult result)
Definition: PlayerStorage.cpp:5675
void SendActionButtons(uint32 state) const
Definition: Player.cpp:5538

References Player::_LoadActions(), GetPlayer(), and Player::SendActionButtons().

◆ HandleLogoutCancelOpcode()

void WorldSession::HandleLogoutCancelOpcode ( WorldPackets::Character::LogoutCancel logoutCancel)
482{
483 // Player have already logged out serverside, too late to cancel
484 if (!GetPlayer())
485 return;
486
488
490
491 // not remove flags if can't free move - its not set in Logout request code.
492 if (GetPlayer()->CanFreeMove())
493 {
494 GetPlayer()->SetRooted(false);
495
498 }
499}
@ UNIT_STAND_STATE_STAND
Definition: UnitDefines.h:32
@ UNIT_FLAG_STUNNED
Definition: UnitDefines.h:247
void SetRooted(bool apply, bool isStun=false)
Definition: Unit.cpp:18169
Definition: CharacterPackets.h:83
void SetLogoutStartTime(time_t requestTime)
Engage the logout process for the user.
Definition: WorldSession.h:388

References GetPlayer(), Unit::RemoveUnitFlag(), SendPacket(), SetLogoutStartTime(), Unit::SetRooted(), Unit::SetStandState(), UNIT_FLAG_STUNNED, and UNIT_STAND_STATE_STAND.

Referenced by OpcodeTable::Initialize().

◆ HandleLogoutRequestOpcode()

void WorldSession::HandleLogoutRequestOpcode ( WorldPackets::Character::LogoutRequest logoutRequest)
Todo:
: Possibly add RBAC permission to log out in combat
418{
419 LOG_DEBUG("network", "WORLD: Recvd CMSG_LOGOUT_REQUEST Message, security - {}", GetSecurity());
420
421 if (ObjectGuid lguid = GetPlayer()->GetLootGUID())
422 DoLootRelease(lguid);
423
424 bool instantLogout = ((GetSecurity() >= 0 && uint32(GetSecurity()) >= sWorld->getIntConfig(CONFIG_INSTANT_LOGOUT))
426
427 bool preventAfkSanctuaryLogout = sWorld->getIntConfig(CONFIG_AFK_PREVENT_LOGOUT) == 1
428 && GetPlayer()->isAFK() && sAreaTableStore.LookupEntry(GetPlayer()->GetAreaId())->IsSanctuary();
429
430 bool preventAfkLogout = sWorld->getIntConfig(CONFIG_AFK_PREVENT_LOGOUT) == 2
431 && GetPlayer()->isAFK();
432
434 bool canLogoutInCombat = GetPlayer()->HasPlayerFlag(PLAYER_FLAGS_RESTING);
435
436 uint32 reason = 0;
437 if (GetPlayer()->IsInCombat() && !canLogoutInCombat)
438 reason = 1;
439 else if (GetPlayer()->m_movementInfo.HasMovementFlag(MOVEMENTFLAG_FALLING | MOVEMENTFLAG_FALLING_FAR))
440 reason = 3; // is jumping or falling
441 else if (preventAfkSanctuaryLogout || preventAfkLogout || GetPlayer()->duel || GetPlayer()->HasAura(9454)) // is dueling or frozen by GM via freeze command
442 reason = 2; // FIXME - Need the correct value
443
445 logoutResponse.LogoutResult = reason;
446 logoutResponse.Instant = instantLogout;
447 SendPacket(logoutResponse.Write());
448
449 if (reason)
450 {
452 return;
453 }
454
455 //instant logout in taverns/cities or on taxi or for admins, gm's, mod's if its enabled in worldserver.conf
456 if (instantLogout)
457 {
458 LogoutPlayer(true);
459 return;
460 }
461
462 // not set flags if player can't free move to prevent lost state at logout cancel
463 if (GetPlayer()->CanFreeMove())
464 {
465 if (GetPlayer()->getStandState() == UNIT_STAND_STATE_STAND)
466 {
468 }
469
470 GetPlayer()->SetRooted(true);
472 }
473
475}
@ CONFIG_INSTANT_LOGOUT
Definition: IWorld.h:305
@ CONFIG_AFK_PREVENT_LOGOUT
Definition: IWorld.h:383
@ MOVEMENTFLAG_FALLING
Definition: UnitDefines.h:356
@ MOVEMENTFLAG_FALLING_FAR
Definition: UnitDefines.h:357
@ UNIT_STAND_STATE_SIT
Definition: UnitDefines.h:33
@ PLAYER_FLAGS_RESTING
Definition: Player.h:479
void SetUnitFlag(UnitFlags flags)
UnitFlags available in UnitDefines.h.
Definition: Unit.h:683
Definition: CharacterPackets.h:56
WorldPacket const * Write() override
Definition: CharacterPackets.cpp:30
uint32 LogoutResult
Definition: CharacterPackets.h:62
bool Instant
Definition: CharacterPackets.h:63

References CONFIG_AFK_PREVENT_LOGOUT, CONFIG_INSTANT_LOGOUT, DoLootRelease(), GameTime::GetGameTime(), GetPlayer(), GetSecurity(), Player::HasPlayerFlag(), WorldPackets::Character::LogoutResponse::Instant, Player::isAFK(), Unit::IsInCombat(), Unit::IsInFlight(), LOG_DEBUG, LogoutPlayer(), WorldPackets::Character::LogoutResponse::LogoutResult, MOVEMENTFLAG_FALLING, MOVEMENTFLAG_FALLING_FAR, PLAYER_FLAGS_RESTING, sAreaTableStore, SendPacket(), SetLogoutStartTime(), Unit::SetRooted(), Unit::SetStandState(), Unit::SetUnitFlag(), sWorld, UNIT_FLAG_STUNNED, UNIT_STAND_STATE_SIT, UNIT_STAND_STATE_STAND, and WorldPackets::Character::LogoutResponse::Write().

Referenced by OpcodeTable::Initialize().

◆ HandleLootMasterGiveOpcode()

void WorldSession::HandleLootMasterGiveOpcode ( WorldPacket recvPacket)
422{
423 uint8 slotid;
424 ObjectGuid lootguid, target_playerguid;
425
426 recvData >> lootguid >> slotid >> target_playerguid;
427
429 {
431 return;
432 }
433
434 Player* target = ObjectAccessor::GetPlayer(*_player, target_playerguid);
435 if (!target)
436 {
438 return;
439 }
440
441 LOG_DEBUG("network", "WorldSession::HandleLootMasterGiveOpcode (CMSG_LOOT_MASTER_GIVE, 0x02A3) Target = [{}].", target->GetName());
442
443 if (_player->GetLootGUID() != lootguid)
444 {
446 return;
447 }
448
449 if (!_player->IsInRaidWith(target))
450 {
452 //LOG_DEBUG("network", "MasterLootItem: Player {} tried to give an item to ineligible player {} !", GetPlayer()->GetName(), target->GetName());
453 return;
454 }
455
456 Loot* loot = nullptr;
457
458 if (GetPlayer()->GetLootGUID().IsCreatureOrVehicle())
459 {
460 Creature* creature = GetPlayer()->GetMap()->GetCreature(lootguid);
461 if (!creature)
462 return;
463
464 loot = &creature->loot;
465 }
466 else if (GetPlayer()->GetLootGUID().IsGameObject())
467 {
468 GameObject* pGO = GetPlayer()->GetMap()->GetGameObject(lootguid);
469 if (!pGO)
470 return;
471
472 loot = &pGO->loot;
473 }
474
475 if (!loot)
476 return;
477
478 if (slotid >= loot->items.size() + loot->quest_items.size())
479 {
480 LOG_DEBUG("loot", "MasterLootItem: Player {} might be using a hack! (slot {}, size {})", GetPlayer()->GetName(), slotid, (unsigned long)loot->items.size());
481 return;
482 }
483
484 LootItem& item = slotid >= loot->items.size() ? loot->quest_items[slotid - loot->items.size()] : loot->items[slotid];
485
486 ItemPosCountVec dest;
487 InventoryResult msg = target->CanStoreNewItem(NULL_BAG, NULL_SLOT, dest, item.itemid, item.count);
488 if (!item.AllowedForPlayer(target, loot->sourceWorldObjectGUID))
490 if (msg != EQUIP_ERR_OK)
491 {
494 else if (msg == EQUIP_ERR_INVENTORY_FULL)
496 else
498
499 return;
500 }
501
502 // list of players allowed to receive this item in trade
503 AllowedLooterSet looters = item.GetAllowedLooters();
504
505 // not move item from loot to target inventory
506 Item* newitem = target->StoreNewItem(dest, item.itemid, true, item.randomPropertyId, looters);
507 target->SendNewItem(newitem, uint32(item.count), false, false, true);
508 target->UpdateLootAchievements(&item, loot);
509
510 // mark as looted
511 item.count = 0;
512 item.is_looted = true;
513
514 loot->NotifyItemRemoved(slotid);
515 --loot->unlootedCount;
516}
GuidSet AllowedLooterSet
Definition: LootMgr.h:152
@ MASTER_LOOT
Definition: LootMgr.h:61
@ LOOT_ERROR_MASTER_OTHER
Definition: LootMgr.h:107
@ LOOT_ERROR_MASTER_INV_FULL
Definition: LootMgr.h:105
@ LOOT_ERROR_MASTER_UNIQUE_ITEM
Definition: LootMgr.h:106
@ LOOT_ERROR_PLAYER_NOT_FOUND
Definition: LootMgr.h:103
@ EQUIP_ERR_CANT_CARRY_MORE_OF_THIS
Definition: Item.h:64
@ EQUIP_ERR_INVENTORY_FULL
Definition: Item.h:97
@ EQUIP_ERR_YOU_CAN_NEVER_USE_THAT_ITEM
Definition: Item.h:57
void UpdateLootAchievements(LootItem *item, Loot *loot)
Definition: PlayerUpdates.cpp:2117
void SendNewItem(Item *item, uint32 count, bool received, bool created, bool broadcast=false, bool sendChatMessage=true)
Definition: PlayerStorage.cpp:4752
Item * StoreNewItem(ItemPosCountVec const &pos, uint32 item, bool update, int32 randomPropertyId=0)
Definition: PlayerStorage.cpp:2526
InventoryResult CanStoreNewItem(uint8 bag, uint8 slot, ItemPosCountVec &dest, uint32 item, uint32 count, uint32 *no_space_count=nullptr) const
Definition: Player.h:1274
bool IsInRaidWith(Unit const *unit) const
Definition: Unit.cpp:18762
ObjectGuid GetMasterLooterGuid() const
Definition: Group.cpp:2326
LootMethod GetLootMethod() const
Definition: Group.cpp:2316
bool AllowedForPlayer(Player const *player, ObjectGuid source) const
Definition: LootMgr.cpp:410
int32 randomPropertyId
Definition: LootMgr.h:159
const AllowedLooterSet & GetAllowedLooters() const
Definition: LootMgr.h:182
ObjectGuid sourceWorldObjectGUID
Definition: LootMgr.h:330
std::vector< LootItem > items
Definition: LootMgr.h:320
std::vector< LootItem > quest_items
Definition: LootMgr.h:321

References _player, LootItem::AllowedForPlayer(), Player::CanStoreNewItem(), LootItem::count, EQUIP_ERR_CANT_CARRY_MORE_OF_THIS, EQUIP_ERR_INVENTORY_FULL, EQUIP_ERR_OK, EQUIP_ERR_YOU_CAN_NEVER_USE_THAT_ITEM, LootItem::GetAllowedLooters(), Map::GetCreature(), Map::GetGameObject(), Player::GetGroup(), Object::GetGUID(), Player::GetLootGUID(), Group::GetLootMethod(), WorldObject::GetMap(), Group::GetMasterLooterGuid(), WorldObject::GetName(), GetPlayer(), ObjectAccessor::GetPlayer(), LootItem::is_looted, Unit::IsInRaidWith(), LootItem::itemid, Loot::items, LOG_DEBUG, Creature::loot, GameObject::loot, LOOT_ERROR_DIDNT_KILL, LOOT_ERROR_MASTER_INV_FULL, LOOT_ERROR_MASTER_OTHER, LOOT_ERROR_MASTER_UNIQUE_ITEM, LOOT_ERROR_PLAYER_NOT_FOUND, MASTER_LOOT, Loot::NotifyItemRemoved(), NULL_BAG, NULL_SLOT, Loot::quest_items, LootItem::randomPropertyId, Player::SendLootError(), Player::SendNewItem(), Loot::sourceWorldObjectGUID, Player::StoreNewItem(), Loot::unlootedCount, and Player::UpdateLootAchievements().

Referenced by OpcodeTable::Initialize().

◆ HandleLootMethodOpcode()

void WorldSession::HandleLootMethodOpcode ( WorldPacket recvPacket)

error handling

464{
465 uint32 lootMethod;
466 ObjectGuid lootMaster;
467 uint32 lootThreshold;
468 recvData >> lootMethod >> lootMaster >> lootThreshold;
469
470 Group* group = GetPlayer()->GetGroup();
471 if (!group)
472 return;
473
475 // Xinef: Check if group is LFG
476 if (!group->IsLeader(GetPlayer()->GetGUID()) || group->isLFGGroup(true))
477 return;
478
479 if (lootMethod > NEED_BEFORE_GREED)
480 return;
481
482 if (lootThreshold < ITEM_QUALITY_UNCOMMON || lootThreshold > ITEM_QUALITY_ARTIFACT)
483 return;
484
485 if (lootMethod == MASTER_LOOT && !group->IsMember(lootMaster))
486 return;
487 /********************/
488
489 // everything's fine, do it
490 group->SetLootMethod((LootMethod)lootMethod);
491 group->SetMasterLooterGuid(lootMaster);
492 group->SetLootThreshold((ItemQualities)lootThreshold);
493 group->SendUpdate();
494}
LootMethod
Definition: LootMgr.h:58
@ NEED_BEFORE_GREED
Definition: LootMgr.h:63
ItemQualities
Definition: SharedDefines.h:328
@ ITEM_QUALITY_ARTIFACT
Definition: SharedDefines.h:335
void SetLootMethod(LootMethod method)
Definition: Group.cpp:2230
void SetLootThreshold(ItemQualities threshold)
Definition: Group.cpp:2245
void SetMasterLooterGuid(ObjectGuid guid)
Definition: Group.cpp:2240

References Player::GetGroup(), GetPlayer(), Group::IsLeader(), Group::isLFGGroup(), Group::IsMember(), ITEM_QUALITY_ARTIFACT, MASTER_LOOT, NEED_BEFORE_GREED, Group::SendUpdate(), Group::SetLootMethod(), Group::SetLootThreshold(), and Group::SetMasterLooterGuid().

Referenced by OpcodeTable::Initialize().

◆ HandleLootMoneyOpcode()

void WorldSession::HandleLootMoneyOpcode ( WorldPacket recvPacket)
115{
116 LOG_DEBUG("network", "WORLD: CMSG_LOOT_MONEY");
117
118 Player* player = GetPlayer();
119 ObjectGuid guid = player->GetLootGUID();
120 if (!guid)
121 return;
122
123 Loot* loot = nullptr;
124 bool shareMoney = true;
125
126 switch (guid.GetHigh())
127 {
128 case HighGuid::GameObject:
129 {
130 GameObject* go = GetPlayer()->GetMap()->GetGameObject(guid);
131
132 // do not check distance for GO if player is the owner of it (ex. fishing bobber)
133 if (go && ((go->GetOwnerGUID() == player->GetGUID() || go->IsWithinDistInMap(player))))
134 {
135 loot = &go->loot;
136 }
137
138 break;
139 }
140 case HighGuid::Corpse: // remove insignia ONLY in BG
141 {
142 Corpse* bones = ObjectAccessor::GetCorpse(*player, guid);
143
144 if (bones && bones->IsWithinDistInMap(player, INTERACTION_DISTANCE))
145 {
146 loot = &bones->loot;
147 shareMoney = false;
148 }
149
150 break;
151 }
152 case HighGuid::Item:
153 {
154 if (Item* item = player->GetItemByGuid(guid))
155 {
156 loot = &item->loot;
157 shareMoney = false;
158 }
159 break;
160 }
161 case HighGuid::Unit:
162 case HighGuid::Vehicle:
163 {
164 Creature* creature = player->GetMap()->GetCreature(guid);
165 bool lootAllowed = creature && creature->IsAlive() == (player->IsClass(CLASS_ROGUE, CLASS_CONTEXT_ABILITY) && creature->loot.loot_type == LOOT_PICKPOCKETING);
166 if (lootAllowed && creature->IsWithinDistInMap(player, INTERACTION_DISTANCE))
167 {
168 loot = &creature->loot;
169 if (creature->IsAlive())
170 shareMoney = false;
171 }
172 else
173 player->SendLootError(guid, lootAllowed ? LOOT_ERROR_TOO_FAR : LOOT_ERROR_DIDNT_KILL);
174 break;
175 }
176 default:
177 return; // unlootable type
178 }
179
180 if (loot)
181 {
182 sScriptMgr->OnBeforeLootMoney(player, loot);
183 loot->NotifyMoneyRemoved();
184 if (shareMoney && player->GetGroup()) //item, pickpocket and players can be looted only single player
185 {
186 Group* group = player->GetGroup();
187
188 std::vector<Player*> playersNear;
189 for (GroupReference* itr = group->GetFirstMember(); itr != nullptr; itr = itr->next())
190 {
191 Player* member = itr->GetSource();
192 if (!member)
193 continue;
194
195 if (player->IsAtLootRewardDistance(member))
196 playersNear.push_back(member);
197 }
198
199 uint32 goldPerPlayer = uint32((loot->gold) / (playersNear.size()));
200
201 for (std::vector<Player*>::const_iterator i = playersNear.begin(); i != playersNear.end(); ++i)
202 {
203 (*i)->ModifyMoney(goldPerPlayer);
204 (*i)->UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_LOOT_MONEY, goldPerPlayer);
205
207 data << uint32(goldPerPlayer);
208 data << uint8(playersNear.size() > 1 ? 0 : 1); // Controls the text displayed in chat. 0 is "Your share is..." and 1 is "You loot..."
209 (*i)->GetSession()->SendPacket(&data);
210 }
211 }
212 else
213 {
214 sScriptMgr->OnAfterCreatureLootMoney(player);
215 player->ModifyMoney(loot->gold);
217
219 data << uint32(loot->gold);
220 data << uint8(1); // "You loot..."
221 SendPacket(&data);
222 }
223
224 sScriptMgr->OnLootMoney(player, loot->gold);
225
226 loot->gold = 0;
227
228 // Delete the money loot record from the DB
229 if (loot->containerGUID)
230 sLootItemStorage->RemoveStoredLootMoney(loot->containerGUID, loot);
231
232 // Delete container if empty
233 if (loot->isLooted() && guid.IsItem())
234 DoLootRelease(guid);
235 }
236}
#define sLootItemStorage
Definition: LootItemStorage.h:75
@ ACHIEVEMENT_CRITERIA_TYPE_LOOT_MONEY
Definition: DBCEnums.h:179
@ SMSG_LOOT_MONEY_NOTIFY
Definition: Opcodes.h:385
HighGuid GetHigh() const
Definition: ObjectGuid.h:143
bool IsAtLootRewardDistance(WorldObject const *pRewardSource) const
Definition: Player.cpp:12785
ObjectGuid containerGUID
Definition: LootMgr.h:329
void NotifyMoneyRemoved()
Definition: LootMgr.cpp:782
uint32 gold
Definition: LootMgr.h:322

References ACHIEVEMENT_CRITERIA_TYPE_LOOT_MONEY, CLASS_CONTEXT_ABILITY, CLASS_ROGUE, Loot::containerGUID, DoLootRelease(), ObjectAccessor::GetCorpse(), Map::GetCreature(), Group::GetFirstMember(), Map::GetGameObject(), Player::GetGroup(), Object::GetGUID(), ObjectGuid::GetHigh(), Player::GetItemByGuid(), Player::GetLootGUID(), WorldObject::GetMap(), GameObject::GetOwnerGUID(), GetPlayer(), Loot::gold, INTERACTION_DISTANCE, Unit::IsAlive(), Player::IsAtLootRewardDistance(), Player::IsClass(), ObjectGuid::IsItem(), Loot::isLooted(), GameObject::IsWithinDistInMap(), WorldObject::IsWithinDistInMap(), LOG_DEBUG, Corpse::loot, Creature::loot, GameObject::loot, LOOT_ERROR_DIDNT_KILL, LOOT_ERROR_TOO_FAR, LOOT_PICKPOCKETING, Loot::loot_type, Player::ModifyMoney(), GroupReference::next(), Loot::NotifyMoneyRemoved(), Player::SendLootError(), SendPacket(), sLootItemStorage, SMSG_LOOT_MONEY_NOTIFY, sScriptMgr, and Player::UpdateAchievementCriteria().

Referenced by OpcodeTable::Initialize().

◆ HandleLootOpcode()

void WorldSession::HandleLootOpcode ( WorldPacket recvPacket)
239{
240 LOG_DEBUG("network", "WORLD: CMSG_LOOT");
241
242 ObjectGuid guid;
243 recvData >> guid;
244
245 // Check possible cheat
246 if (!GetPlayer()->IsAlive() || !guid.IsCreatureOrVehicle())
247 return;
248
249 // interrupt cast
250 if (GetPlayer()->IsNonMeleeSpellCast(false))
252
254}
void SendLoot(ObjectGuid guid, LootType loot_type)
Definition: Player.cpp:7773

References GetPlayer(), Unit::InterruptNonMeleeSpells(), ObjectGuid::IsCreatureOrVehicle(), LOG_DEBUG, LOOT_CORPSE, and Player::SendLoot().

Referenced by OpcodeTable::Initialize().

◆ HandleLootReleaseOpcode()

void WorldSession::HandleLootReleaseOpcode ( WorldPacket recvPacket)
257{
258 LOG_DEBUG("network", "WORLD: CMSG_LOOT_RELEASE");
259
260 // cheaters can modify lguid to prevent correct apply loot release code and re-loot
261 // use internal stored guid
262 ObjectGuid guid;
263 recvData >> guid;
264
265 if (ObjectGuid lguid = GetPlayer()->GetLootGUID())
266 if (lguid == guid)
267 DoLootRelease(lguid);
268}

References DoLootRelease(), GetPlayer(), and LOG_DEBUG.

Referenced by OpcodeTable::Initialize().

◆ HandleLootRoll()

void WorldSession::HandleLootRoll ( WorldPacket recvData)
497{
498 ObjectGuid guid;
499 uint32 itemSlot;
500 uint8 rollType;
501 recvData >> guid; // guid of the item rolled
502 recvData >> itemSlot;
503 recvData >> rollType; // 0: pass, 1: need, 2: greed
504
505 Group* group = GetPlayer()->GetGroup();
506 if (!group)
507 return;
508
509 group->CountRollVote(GetPlayer()->GetGUID(), guid, rollType);
510
511 switch (rollType)
512 {
513 case ROLL_NEED:
515 break;
516 case ROLL_GREED:
518 break;
519 case ROLL_DISENCHANT:
521 break;
522 }
523}
@ ROLL_GREED
Definition: LootMgr.h:36
@ ROLL_NEED
Definition: LootMgr.h:35
@ ROLL_DISENCHANT
Definition: LootMgr.h:37
@ ACHIEVEMENT_CRITERIA_TYPE_ROLL_GREED
Definition: DBCEnums.h:201
@ ACHIEVEMENT_CRITERIA_TYPE_ROLL_DISENCHANT
Definition: DBCEnums.h:222
@ ACHIEVEMENT_CRITERIA_TYPE_ROLL_NEED
Definition: DBCEnums.h:200
bool CountRollVote(ObjectGuid playerGUID, ObjectGuid Guid, uint8 Choise)
Definition: Group.cpp:1360

References ACHIEVEMENT_CRITERIA_TYPE_ROLL_DISENCHANT, ACHIEVEMENT_CRITERIA_TYPE_ROLL_GREED, ACHIEVEMENT_CRITERIA_TYPE_ROLL_NEED, Group::CountRollVote(), Player::GetGroup(), GetPlayer(), ROLL_DISENCHANT, ROLL_GREED, ROLL_NEED, and Player::UpdateAchievementCriteria().

Referenced by OpcodeTable::Initialize().

◆ HandleMailCreateTextItem()

void WorldSession::HandleMailCreateTextItem ( WorldPacket recvData)
758{
759 ObjectGuid mailbox;
760 uint32 mailId;
761
762 recvData >> mailbox;
763 recvData >> mailId;
764
765 if (!CanOpenMailBox(mailbox))
766 return;
767
768 Player* player = _player;
769
770 Mail* m = player->GetMail(mailId);
771 if (!m || (m->body.empty() && !m->mailTemplateId) || m->state == MAIL_STATE_DELETED || m->deliver_time > GameTime::GetGameTime().count() || (m->checked & MAIL_CHECK_MASK_COPIED))
772 {
774 return;
775 }
776
777 Item* bodyItem = new Item; // This is not bag and then can be used new Item.
778 if (!bodyItem->Create(sObjectMgr->GetGenerator<HighGuid::Item>().Generate(), MAIL_BODY_ITEM_TEMPLATE, player))
779 {
780 delete bodyItem;
781 return;
782 }
783
784 // in mail template case we need create new item text
785 if (m->mailTemplateId)
786 {
787 MailTemplateEntry const* mailTemplateEntry = sMailTemplateStore.LookupEntry(m->mailTemplateId);
788 if (!mailTemplateEntry)
789 {
791 delete bodyItem;
792 return;
793 }
794
795 bodyItem->SetText(mailTemplateEntry->content[GetSessionDbcLocale()]);
796 }
797 else
798 bodyItem->SetText(m->body);
799
802
803 LOG_DEBUG("network.opcode", "HandleMailCreateTextItem mailid={}", mailId);
804
805 ItemPosCountVec dest;
806 uint8 msg = _player->CanStoreItem(NULL_BAG, NULL_SLOT, dest, bodyItem, false);
807 if (msg == EQUIP_ERR_OK)
808 {
811 player->m_mailsUpdated = true;
812
813 player->StoreItem(dest, bodyItem, true);
815 }
816 else
817 {
819 delete bodyItem;
820 }
821}
DBCStorage< MailTemplateEntry > sMailTemplateStore(MailTemplateEntryfmt)
@ ITEM_FIELD_FLAGS
Definition: UpdateFields.h:42
@ ITEM_FIELD_CREATOR
Definition: UpdateFields.h:37
@ ITEM_FLAG_MAIL_TEXT_MASK
Definition: ItemTemplate.h:142
@ MAIL_STATE_CHANGED
Definition: Mail.h:70
#define MAIL_BODY_ITEM_TEMPLATE
Definition: Mail.h:33
@ MAIL_MADE_PERMANENT
Definition: SharedDefines.h:3505
@ MAIL_ERR_EQUIP_ERROR
Definition: SharedDefines.h:3511
@ MAIL_OK
Definition: SharedDefines.h:3510
@ MAIL_ERR_INTERNAL_ERROR
Definition: SharedDefines.h:3516
virtual bool Create(ObjectGuid::LowType guidlow, uint32 itemid, Player const *owner)
Definition: Item.cpp:283
void SetText(std::string const &text)
Definition: Item.h:309
void SetFlag(uint16 index, uint32 newFlag)
Definition: Object.cpp:845
void SetUInt32Value(uint16 index, uint32 value)
Definition: Object.cpp:650
void SendMailResult(uint32 mailId, MailResponseType mailAction, MailResponseResult mailError, uint32 equipError=0, ObjectGuid::LowType item_guid=0, uint32 item_count=0)
Definition: Player.cpp:2853
bool m_mailsUpdated
Definition: Player.h:1586
Mail * GetMail(uint32 id)
Definition: Player.cpp:3785
uint32 sender
Definition: Mail.h:173
std::string body
Definition: Mail.h:176
time_t deliver_time
Definition: Mail.h:180
uint32 checked
Definition: Mail.h:183
MailState state
Definition: Mail.h:184
uint16 mailTemplateId
Definition: Mail.h:172
LocaleConstant GetSessionDbcLocale() const
Definition: WorldSession.h:497
Definition: DBCStructure.h:1316
char const * content[16]
Definition: DBCStructure.h:1320

References _player, Mail::body, CanOpenMailBox(), Player::CanStoreItem(), Mail::checked, MailTemplateEntry::content, Item::Create(), Mail::deliver_time, EQUIP_ERR_OK, GameTime::GetGameTime(), Player::GetMail(), GetSessionDbcLocale(), ITEM_FIELD_CREATOR, ITEM_FIELD_FLAGS, ITEM_FLAG_MAIL_TEXT_MASK, LOG_DEBUG, Player::m_mailsUpdated, MAIL_BODY_ITEM_TEMPLATE, MAIL_CHECK_MASK_COPIED, MAIL_ERR_EQUIP_ERROR, MAIL_ERR_INTERNAL_ERROR, MAIL_MADE_PERMANENT, MAIL_OK, MAIL_STATE_CHANGED, MAIL_STATE_DELETED, Mail::mailTemplateId, NULL_BAG, NULL_SLOT, Mail::sender, Player::SendMailResult(), Object::SetFlag(), Item::SetText(), Object::SetUInt32Value(), sMailTemplateStore, sObjectMgr, Mail::state, and Player::StoreItem().

Referenced by OpcodeTable::Initialize().

◆ HandleMailDelete()

void WorldSession::HandleMailDelete ( WorldPacket recvData)
372{
373 ObjectGuid mailbox;
374 uint32 mailId;
375 recvData >> mailbox;
376 recvData >> mailId;
377 recvData.read_skip<uint32>(); // mailTemplateId
378
379 if (!CanOpenMailBox(mailbox))
380 return;
381
382 Mail* m = _player->GetMail(mailId);
383 Player* player = _player;
384 player->m_mailsUpdated = true;
385 if (m)
386 {
387 // delete shouldn't show up for COD mails
388 if (m->COD)
389 {
391 return;
392 }
393
395
396 sCharacterCache->DecreaseCharacterMailCount(player->GetGUID());
397 }
398 player->SendMailResult(mailId, MAIL_DELETED, MAIL_OK);
399}
@ MAIL_DELETED
Definition: SharedDefines.h:3504
uint32 COD
Definition: Mail.h:182

References _player, CanOpenMailBox(), Mail::COD, Object::GetGUID(), Player::GetMail(), Player::m_mailsUpdated, MAIL_DELETED, MAIL_ERR_INTERNAL_ERROR, MAIL_OK, MAIL_STATE_DELETED, ByteBuffer::read_skip(), sCharacterCache, Player::SendMailResult(), and Mail::state.

Referenced by OpcodeTable::Initialize().

◆ HandleMailMarkAsRead()

void WorldSession::HandleMailMarkAsRead ( WorldPacket recvData)
349{
350 ObjectGuid mailbox;
351 uint32 mailId;
352 recvData >> mailbox;
353 recvData >> mailId;
354
355 if (!CanOpenMailBox(mailbox))
356 return;
357
358 Player* player = _player;
359 Mail* m = player->GetMail(mailId);
360 if (m && m->state != MAIL_STATE_DELETED)
361 {
362 if (player->unReadMails)
363 --player->unReadMails;
365 player->m_mailsUpdated = true;
367 }
368}
@ MAIL_CHECK_MASK_READ
Definition: Mail.h:48
uint8 unReadMails
Definition: Player.h:1650

References _player, CanOpenMailBox(), Mail::checked, Player::GetMail(), Player::m_mailsUpdated, MAIL_CHECK_MASK_READ, MAIL_STATE_CHANGED, MAIL_STATE_DELETED, Mail::state, and Player::unReadMails.

Referenced by OpcodeTable::Initialize().

◆ HandleMailReturnToSender()

void WorldSession::HandleMailReturnToSender ( WorldPacket recvData)
402{
403 ObjectGuid mailbox;
404 uint32 mailId;
405 recvData >> mailbox;
406 recvData >> mailId;
407 recvData.read_skip<uint64>(); // original sender GUID for return to, not used
408
409 if (!CanOpenMailBox(mailbox))
410 return;
411
412 Player* player = _player;
413 Mail* m = player->GetMail(mailId);
414 if (!m || m->state == MAIL_STATE_DELETED || m->deliver_time > GameTime::GetGameTime().count())
415 {
417 return;
418 }
419
420 if (m->HasItems())
421 {
422 for (MailItemInfoVec::iterator itr = m->items.begin(); itr != m->items.end(); ++itr)
423 {
424 Item* item = player->GetMItem(itr->item_guid);
425 if (item && !sScriptMgr->CanSendMail(player, ObjectGuid(HighGuid::Player, m->sender), mailbox, m->subject, m->body, m->money, m->COD, item))
426 {
428 return;
429 }
430 }
431 }
432 else if (!sScriptMgr->CanSendMail(player, ObjectGuid(HighGuid::Player, m->sender), mailbox, m->subject, m->body, m->money, m->COD, nullptr))
433 {
435 return;
436 }
437
438 //we can return mail now
439 //so firstly delete the old one
440 CharacterDatabaseTransaction trans = CharacterDatabase.BeginTransaction();
441
443 stmt->SetData(0, mailId);
444 trans->Append(stmt);
445
446 stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_MAIL_ITEM_BY_ID);
447 stmt->SetData(0, mailId);
448 trans->Append(stmt);
449
450 player->RemoveMail(mailId);
451
452 // only return mail if the player exists (and delete if not existing)
453 if (m->messageType == MAIL_NORMAL && m->sender)
454 {
455 MailDraft draft(m->subject, m->body);
456 if (m->mailTemplateId)
457 draft = MailDraft(m->mailTemplateId, false); // items already included
458
459 if (m->HasItems())
460 {
461 for (MailItemInfoVec::iterator itr2 = m->items.begin(); itr2 != m->items.end(); ++itr2)
462 {
463 Item* item = player->GetMItem(itr2->item_guid);
464 if (item)
465 draft.AddItem(item);
466
467 player->RemoveMItem(itr2->item_guid);
468 }
469 }
470 draft.AddMoney(m->money).SendReturnToSender(GetAccountId(), m->receiver, m->sender, trans);
471 }
472
473 CharacterDatabase.CommitTransaction(trans);
474
475 delete m; //we can deallocate old mail
477
478 sCharacterCache->DecreaseCharacterMailCount(player->GetGUID());
479}
@ CHAR_DEL_MAIL_BY_ID
Definition: CharacterDatabase.h:110
@ CHAR_DEL_MAIL_ITEM_BY_ID
Definition: CharacterDatabase.h:380
@ MAIL_RETURNED_TO_SENDER
Definition: SharedDefines.h:3503
void RemoveMail(uint32 id)
Definition: Player.cpp:2840
bool RemoveMItem(ObjectGuid::LowType itemLowGuid)
Definition: Player.h:1670
bool HasItems() const
Definition: Mail.h:207
ObjectGuid::LowType receiver
Definition: Mail.h:174
uint8 messageType
Definition: Mail.h:170
std::string subject
Definition: Mail.h:175
std::vector< MailItemInfo > items
Definition: Mail.h:177
uint32 money
Definition: Mail.h:181

References _player, MailDraft::AddItem(), MailDraft::AddMoney(), Mail::body, CanOpenMailBox(), CHAR_DEL_MAIL_BY_ID, CHAR_DEL_MAIL_ITEM_BY_ID, CharacterDatabase, Mail::COD, Mail::deliver_time, GetAccountId(), GameTime::GetGameTime(), Object::GetGUID(), Player::GetMail(), Player::GetMItem(), Mail::HasItems(), Mail::items, MAIL_ERR_INTERNAL_ERROR, MAIL_NORMAL, MAIL_OK, MAIL_RETURNED_TO_SENDER, MAIL_STATE_DELETED, Mail::mailTemplateId, Mail::messageType, Mail::money, ByteBuffer::read_skip(), Mail::receiver, Player::RemoveMail(), Player::RemoveMItem(), sCharacterCache, Mail::sender, Player::SendMailResult(), MailDraft::SendReturnToSender(), PreparedStatementBase::SetData(), sScriptMgr, Mail::state, and Mail::subject.

Referenced by OpcodeTable::Initialize().

◆ HandleMailTakeItem()

void WorldSession::HandleMailTakeItem ( WorldPacket recvData)
483{
484 ObjectGuid mailbox;
485 uint32 mailId;
486 uint32 itemLowGuid;
487 recvData >> mailbox;
488 recvData >> mailId;
489 recvData >> itemLowGuid; // item guid low
490
491 if (!CanOpenMailBox(mailbox))
492 return;
493
494 Player* player = _player;
495
496 Mail* m = player->GetMail(mailId);
497 if (!m || m->state == MAIL_STATE_DELETED || m->deliver_time > GameTime::GetGameTime().count())
498 {
500 return;
501 }
502
503 // verify that the mail has the item to avoid cheaters taking COD items without paying
504 bool foundItem = false;
505 for (std::vector<MailItemInfo>::const_iterator itr = m->items.begin(); itr != m->items.end(); ++itr)
506 if (itr->item_guid == itemLowGuid)
507 {
508 foundItem = true;
509 break;
510 }
511 if (!foundItem)
512 {
514 return;
515 }
516
517 // prevent cheating with skip client money check
518 if (!player->HasEnoughMoney(m->COD))
519 {
521 return;
522 }
523
524 Item* it = player->GetMItem(itemLowGuid);
525
526 ItemPosCountVec dest;
527 uint8 msg = _player->CanStoreItem(NULL_BAG, NULL_SLOT, dest, it, false);
528 if (msg == EQUIP_ERR_OK)
529 {
530 CharacterDatabaseTransaction trans = CharacterDatabase.BeginTransaction();
531 m->RemoveItem(itemLowGuid);
532 m->removedItems.push_back(itemLowGuid);
533
534 if (m->COD > 0) // if there is COD, take COD money from player and send them to sender by mail
535 {
536 uint32 sender_accId = 0;
538 if (sender)
539 {
540 sender_accId = sender->GetSession()->GetAccountId();
541 }
542 else
543 {
544 sender_accId = sCharacterCache->GetCharacterAccountIdByGuid(ObjectGuid(HighGuid::Player, m->sender));
545 }
546
547 // check player existence
548 if (sender || sender_accId)
549 {
550 MailDraft(m->subject, "")
551 .AddMoney(m->COD)
553
554 if (m->COD >= 10 * GOLD)
555 {
556 std::string senderName;
557 if (!sCharacterCache->GetCharacterNameByGuid(ObjectGuid(HighGuid::Player, m->sender), senderName))
558 {
559 senderName = sObjectMgr->GetAcoreStringForDBCLocale(LANG_UNKNOWN);
560 }
561 std::string subj = m->subject;
563 CharacterDatabase.Execute("INSERT INTO log_money VALUES({}, {}, \"{}\", \"{}\", {}, \"{}\", {}, \"{}\", NOW(), {})",
564 GetAccountId(), player->GetGUID().GetCounter(), player->GetName(), player->GetSession()->GetRemoteAddress(), sender_accId, senderName, m->COD, subj, 1);
565 }
566 }
567
568 player->ModifyMoney(-int32(m->COD));
569 }
570
571 m->COD = 0;
573 player->m_mailsUpdated = true;
574 player->RemoveMItem(it->GetGUID().GetCounter());
575
576 uint32 count = it->GetCount(); // save counts before store and possible merge with deleting
577 it->SetState(ITEM_UNCHANGED); // need to set this state, otherwise item cannot be removed later, if neccessary
578 player->MoveItemToInventory(dest, it, true);
579
580 player->SaveInventoryAndGoldToDB(trans);
581 player->_SaveMail(trans);
582 CharacterDatabase.CommitTransaction(trans);
583
584 player->SendMailResult(mailId, MAIL_ITEM_TAKEN, MAIL_OK, 0, itemLowGuid, count);
585 }
586 else
588}
void CleanStringForMysqlQuery(std::string &str)
Definition: Common.cpp:44
@ LANG_UNKNOWN
Definition: Language.h:77
@ ITEM_UNCHANGED
Definition: Item.h:209
@ MAIL_CHECK_MASK_COD_PAYMENT
This mail was copied. Do not allow making a copy of items in mail.
Definition: Mail.h:51
@ MAIL_ITEM_TAKEN
Definition: SharedDefines.h:3502
@ MAIL_ERR_NOT_ENOUGH_MONEY
Definition: SharedDefines.h:3513
Player * FindPlayerByLowGUID(ObjectGuid::LowType lowguid)
Definition: ObjectAccessor.cpp:251
void MoveItemToInventory(ItemPosCountVec const &dest, Item *pItem, bool update, bool in_characterInventoryDB=false)
Definition: PlayerStorage.cpp:3000
void _SaveMail(CharacterDatabaseTransaction trans)
Definition: PlayerStorage.cpp:7380
Definition: Mail.h:84
Definition: Mail.h:106
MailDraft & AddMoney(uint32 money)
Definition: Mail.h:138
std::vector< uint32 > removedItems
Definition: Mail.h:178
bool RemoveItem(ObjectGuid::LowType item_guid)
Definition: Mail.h:194

References _player, Player::_SaveMail(), MailDraft::AddMoney(), CanOpenMailBox(), Player::CanStoreItem(), CharacterDatabase, CleanStringForMysqlQuery(), Mail::COD, Mail::deliver_time, EQUIP_ERR_OK, ObjectAccessor::FindPlayerByLowGUID(), GetAccountId(), Item::GetCount(), ObjectGuid::GetCounter(), GameTime::GetGameTime(), Object::GetGUID(), Player::GetMail(), Player::GetMItem(), WorldObject::GetName(), GetRemoteAddress(), Player::GetSession(), GOLD, Player::HasEnoughMoney(), ITEM_UNCHANGED, Mail::items, LANG_UNKNOWN, Player::m_mailsUpdated, MAIL_CHECK_MASK_COD_PAYMENT, MAIL_ERR_EQUIP_ERROR, MAIL_ERR_INTERNAL_ERROR, MAIL_ERR_NOT_ENOUGH_MONEY, MAIL_ITEM_TAKEN, MAIL_NORMAL, MAIL_OK, MAIL_STATE_CHANGED, MAIL_STATE_DELETED, Player::ModifyMoney(), Player::MoveItemToInventory(), NULL_BAG, NULL_SLOT, Mail::receiver, Mail::removedItems, Mail::RemoveItem(), Player::RemoveMItem(), Player::SaveInventoryAndGoldToDB(), sCharacterCache, Mail::sender, Player::SendMailResult(), MailDraft::SendMailTo(), Item::SetState(), sObjectMgr, Mail::state, and Mail::subject.

Referenced by OpcodeTable::Initialize().

◆ HandleMailTakeMoney()

void WorldSession::HandleMailTakeMoney ( WorldPacket recvData)
591{
592 ObjectGuid mailbox;
593 uint32 mailId;
594 recvData >> mailbox;
595 recvData >> mailId;
596
597 if (!CanOpenMailBox(mailbox))
598 return;
599
600 Player* player = _player;
601
602 Mail* m = player->GetMail(mailId);
603 if (!m || m->state == MAIL_STATE_DELETED || m->deliver_time > GameTime::GetGameTime().count())
604 {
606 return;
607 }
608
609 if (!player->ModifyMoney(m->money, false))
610 {
612 return;
613 }
614
615 m->money = 0;
617 player->m_mailsUpdated = true;
618
619 player->SendMailResult(mailId, MAIL_MONEY_TAKEN, MAIL_OK);
620
621 // save money and mail to prevent cheating
622 CharacterDatabaseTransaction trans = CharacterDatabase.BeginTransaction();
623 player->SaveGoldToDB(trans);
624 player->_SaveMail(trans);
625 CharacterDatabase.CommitTransaction(trans);
626}
@ MAIL_MONEY_TAKEN
Definition: SharedDefines.h:3501
void SaveGoldToDB(CharacterDatabaseTransaction trans)
Definition: PlayerStorage.cpp:7128

References _player, Player::_SaveMail(), CanOpenMailBox(), CharacterDatabase, Mail::deliver_time, EQUIP_ERR_TOO_MUCH_GOLD, GameTime::GetGameTime(), Player::GetMail(), Player::m_mailsUpdated, MAIL_ERR_EQUIP_ERROR, MAIL_ERR_INTERNAL_ERROR, MAIL_MONEY_TAKEN, MAIL_OK, MAIL_STATE_CHANGED, MAIL_STATE_DELETED, Player::ModifyMoney(), Mail::money, Player::SaveGoldToDB(), Player::SendMailResult(), and Mail::state.

Referenced by OpcodeTable::Initialize().

◆ HandleMessagechatOpcode()

void WorldSession::HandleMessagechatOpcode ( WorldPacket recvPacket)
60{
61 uint32 type;
62 uint32 lang;
63
64 recvData >> type;
65 recvData >> lang;
66
67 if (type >= MAX_CHAT_MSG_TYPE)
68 {
69 LOG_ERROR("network.opcode", "CHAT: Wrong message type received: {}", type);
70 recvData.rfinish();
71 return;
72 }
73
74 if (lang == LANG_UNIVERSAL && type != CHAT_MSG_AFK && type != CHAT_MSG_DND)
75 {
76 LOG_ERROR("entities.player.cheat", "CMSG_MESSAGECHAT: Possible hacking-attempt: {} tried to send a message in universal language", GetPlayerInfo());
78 recvData.rfinish();
79 return;
80 }
81
82 Player* sender = GetPlayer();
83
84 // prevent talking at unknown language (cheating)
85 LanguageDesc const* langDesc = GetLanguageDescByID(lang);
86 if (!langDesc)
87 {
89 recvData.rfinish();
90 return;
91 }
92
93 if (langDesc->skill_id != 0 && !sender->HasSkill(langDesc->skill_id))
94 {
95 // also check SPELL_AURA_COMPREHEND_LANGUAGE (client offers option to speak in that language)
96 bool foundAura = false;
97 for (auto const& auraEff : sender->GetAuraEffectsByType(SPELL_AURA_COMPREHEND_LANGUAGE))
98 {
99 if (auraEff->GetMiscValue() == int32(lang))
100 {
101 foundAura = true;
102 break;
103 }
104 }
105
106 if (!foundAura)
107 {
109 recvData.rfinish();
110 return;
111 }
112 }
113
114 // pussywizard: chatting on most chat types requires 2 hours played to prevent spam/abuse
116 {
117 switch (type)
118 {
119 case CHAT_MSG_ADDON:
120 case CHAT_MSG_PARTY:
121 case CHAT_MSG_RAID:
122 case CHAT_MSG_GUILD:
123 case CHAT_MSG_OFFICER:
124 case CHAT_MSG_AFK:
125 case CHAT_MSG_DND:
131 break;
132 default:
133 {
134 if (sWorld->getBoolConfig(CONFIG_CHAT_MUTE_FIRST_LOGIN) && lang != LANG_ADDON)
135 {
136 uint32 minutes = sWorld->getIntConfig(CONFIG_CHAT_TIME_MUTE_FIRST_LOGIN);
137
138 if (sender->GetTotalPlayedTime() < minutes * MINUTE)
139 {
141 recvData.rfinish();
142 return;
143 }
144 }
145 }
146 }
147 }
148
149 // pussywizard:
150 switch (type)
151 {
152 case CHAT_MSG_SAY:
153 case CHAT_MSG_YELL:
154 case CHAT_MSG_EMOTE:
156 case CHAT_MSG_AFK:
157 case CHAT_MSG_DND:
158 if (sender->IsSpectator())
159 {
160 recvData.rfinish();
161 return;
162 }
163 }
164
165 if (sender->HasAura(1852) && type != CHAT_MSG_WHISPER)
166 {
168 recvData.rfinish();
169 return;
170 }
171
172 if (lang == LANG_ADDON)
173 {
174 // LANG_ADDON is only valid for the following message types
175 switch (type)
176 {
177 case CHAT_MSG_PARTY:
178 case CHAT_MSG_RAID:
179 case CHAT_MSG_GUILD:
181 case CHAT_MSG_WHISPER:
182 // check if addon messages are disabled
183 if (!sWorld->getBoolConfig(CONFIG_ADDON_CHANNEL))
184 {
185 recvData.rfinish();
186 return;
187 }
188 break;
189 default:
190 LOG_ERROR("network", "Player {} ({}) sent a chatmessage with an invalid language/message type combination",
191 GetPlayer()->GetName(), GetPlayer()->GetGUID().ToString());
192
193 recvData.rfinish();
194 return;
195 }
196 }
197 else
198 {
199 // send in universal language if player in .gmon mode (ignore spell effects)
200 if (sender->IsGameMaster())
201 lang = LANG_UNIVERSAL;
202 else
203 {
204 // send in universal language in two side iteration allowed mode
206 lang = LANG_UNIVERSAL;
207 else
208 {
209 switch (type)
210 {
211 case CHAT_MSG_PARTY:
213 case CHAT_MSG_RAID:
216 // allow two side chat at group channel if two side group allowed
218 lang = LANG_UNIVERSAL;
219 break;
220 case CHAT_MSG_GUILD:
221 case CHAT_MSG_OFFICER:
222 // allow two side chat at guild channel if two side guild allowed
224 lang = LANG_UNIVERSAL;
225 break;
226 }
227 }
228 // Overwritten by SPELL_AURA_MOD_LANGUAGE auras (Affects only Say and Yell)
230 if (!ModLangAuras.empty() && (type == CHAT_MSG_SAY || type == CHAT_MSG_YELL))
231 lang = ModLangAuras.front()->GetMiscValue();
232 }
233
234 if (type != CHAT_MSG_AFK && type != CHAT_MSG_DND)
236 }
237
238 std::string to, channel, msg;
239 bool ignoreChecks = false;
240 switch (type)
241 {
242 case CHAT_MSG_SAY:
243 case CHAT_MSG_EMOTE:
244 case CHAT_MSG_YELL:
245 case CHAT_MSG_PARTY:
247 case CHAT_MSG_GUILD:
248 case CHAT_MSG_OFFICER:
249 case CHAT_MSG_RAID:
254 msg = recvData.ReadCString(lang != LANG_ADDON);
255 break;
256 case CHAT_MSG_WHISPER:
257 recvData >> to;
258 msg = recvData.ReadCString(lang != LANG_ADDON);
259 break;
260 case CHAT_MSG_CHANNEL:
261 recvData >> channel;
262 msg = recvData.ReadCString(lang != LANG_ADDON);
263 break;
264 case CHAT_MSG_AFK:
265 case CHAT_MSG_DND:
266 msg = recvData.ReadCString(lang != LANG_ADDON);
267 ignoreChecks = true;
268 break;
269 }
270
271 // Our Warden module also uses SendAddonMessage as a way to communicate Lua check results to the server, see if this is that
272 if (type == CHAT_MSG_GUILD && lang == LANG_ADDON && _warden && _warden->ProcessLuaCheckResponse(msg))
273 {
274 return;
275 }
276
277 // pussywizard:
278 if (msg.length() > 255 || (lang != LANG_ADDON && msg.find("|0") != std::string::npos))
279 return;
280
281 if (!ignoreChecks)
282 {
283 if (msg.empty())
284 return;
285
286 if (lang == LANG_ADDON)
287 {
288 if (AddonChannelCommandHandler(this).ParseCommands(msg.c_str()))
289 return;
290 }
291 else
292 {
293 if (ChatHandler(this).ParseCommands(msg.c_str()))
294 return;
295
296 if (!_player->CanSpeak())
297 {
298 std::string timeStr = secsToTimeString(m_muteTime - GameTime::GetGameTime().count());
300 return;
301 }
302 }
303 }
304
305 // do message validity checks
306 if (lang != LANG_ADDON)
307 {
308 // cut at the first newline or carriage return
309 std::string::size_type pos = msg.find_first_of("\n\r");
310
311 if (pos == 0)
312 {
313 return;
314 }
315 else if (pos != std::string::npos)
316 {
317 msg.erase(pos);
318 }
319
320 // abort on any sort of nasty character
321 for (uint8 c : msg)
322 {
323 if (isNasty(c))
324 {
325 LOG_ERROR("network", "Player {} {} sent a message containing invalid character {} - blocked", GetPlayer()->GetName(),
326 GetPlayer()->GetGUID().ToString(), uint8(c));
327 return;
328 }
329 }
330
331 // collapse multiple spaces into one
333 {
334 auto end = std::unique(msg.begin(), msg.end(), [](char c1, char c2) { return (c1 == ' ') && (c2 == ' '); });
335 msg.erase(end, msg.end());
336 }
337
338 // Validate hyperlinks
340 {
341 return;
342 }
343 }
344
345 else
346 {
348 }
349
350 sScriptMgr->OnBeforeSendChatMessage(_player, type, lang, msg);
351
352 switch (type)
353 {
354 case CHAT_MSG_SAY:
355 case CHAT_MSG_EMOTE:
356 case CHAT_MSG_YELL:
357 {
358 // Prevent cheating
359 if (!sender->IsAlive())
360 return;
361
362 if (sender->GetLevel() < sWorld->getIntConfig(CONFIG_CHAT_SAY_LEVEL_REQ))
363 {
365 return;
366 }
367
368 if (type == CHAT_MSG_SAY)
369 sender->Say(msg, Language(lang));
370 else if (type == CHAT_MSG_EMOTE)
371 sender->TextEmote(msg);
372 else if (type == CHAT_MSG_YELL)
373 sender->Yell(msg, Language(lang));
374 }
375 break;
376 case CHAT_MSG_WHISPER:
377 {
378 if (!normalizePlayerName(to))
379 {
381 break;
382 }
383
384 Player* receiver = ObjectAccessor::FindPlayerByName(to, false);
385 bool senderIsPlayer = AccountMgr::IsPlayerAccount(GetSecurity());
386 bool receiverIsPlayer = AccountMgr::IsPlayerAccount(receiver ? receiver->GetSession()->GetSecurity() : SEC_PLAYER);
387
388 if (sender->GetLevel() < sWorld->getIntConfig(CONFIG_CHAT_WHISPER_LEVEL_REQ) && receiver != sender)
389 {
391 return;
392 }
393
394 if (!receiver || (senderIsPlayer && !receiverIsPlayer && !receiver->isAcceptWhispers() && !receiver->IsInWhisperWhiteList(sender->GetGUID())))
395 {
397 return;
398 }
399
400 if (!sWorld->getBoolConfig(CONFIG_ALLOW_TWO_SIDE_INTERACTION_CHAT) && senderIsPlayer && receiverIsPlayer)
401 if (GetPlayer()->GetTeamId() != receiver->GetTeamId())
402 {
404 return;
405 }
406
407 // pussywizard: optimization
408 if (GetPlayer()->HasAura(1852) && !receiver->IsGameMaster())
409 {
411 return;
412 }
413
414 // If player is a Gamemaster and doesn't accept whisper, we auto-whitelist every player that the Gamemaster is talking to
415 if (!senderIsPlayer && !sender->isAcceptWhispers() && !sender->IsInWhisperWhiteList(receiver->GetGUID()))
416 sender->AddWhisperWhiteList(receiver->GetGUID());
417
418 GetPlayer()->Whisper(msg, Language(lang), receiver);
419 }
420 break;
421 case CHAT_MSG_PARTY:
423 {
424 // if player is in battleground, he cannot say to battleground members by /p
425 Group* group = GetPlayer()->GetOriginalGroup();
426 if (!group)
427 {
428 group = sender->GetGroup();
429 if (!group || group->isBGGroup())
430 return;
431 }
432
433 if (type == CHAT_MSG_PARTY_LEADER && !group->IsLeader(sender->GetGUID()))
434 return;
435
436 if (!sScriptMgr->CanPlayerUseChat(GetPlayer(), type, lang, msg, group))
437 {
438 return;
439 }
440
441 sScriptMgr->OnPlayerChat(GetPlayer(), type, lang, msg, group);
442
443 WorldPacket data;
444 ChatHandler::BuildChatPacket(data, ChatMsg(type), Language(lang), sender, nullptr, msg);
445 group->BroadcastPacket(&data, false, group->GetMemberGroup(GetPlayer()->GetGUID()));
446 }
447 break;
448 case CHAT_MSG_GUILD:
449 {
450 if (GetPlayer()->GetGuildId())
451 {
452 if (Guild* guild = sGuildMgr->GetGuildById(GetPlayer()->GetGuildId()))
453 {
454 if (!sScriptMgr->CanPlayerUseChat(GetPlayer(), type, lang, msg, guild))
455 {
456 return;
457 }
458
459 sScriptMgr->OnPlayerChat(GetPlayer(), type, lang, msg, guild);
460
461 guild->BroadcastToGuild(this, false, msg, lang == LANG_ADDON ? LANG_ADDON : LANG_UNIVERSAL);
462 }
463 }
464 }
465 break;
466 case CHAT_MSG_OFFICER:
467 {
468 if (GetPlayer()->GetGuildId())
469 {
470 if (Guild* guild = sGuildMgr->GetGuildById(GetPlayer()->GetGuildId()))
471 {
472 if (!sScriptMgr->CanPlayerUseChat(GetPlayer(), type, lang, msg, guild))
473 {
474 return;
475 }
476
477 sScriptMgr->OnPlayerChat(GetPlayer(), type, lang, msg, guild);
478
479 guild->BroadcastToGuild(this, true, msg, lang == LANG_ADDON ? LANG_ADDON : LANG_UNIVERSAL);
480 }
481 }
482 }
483 break;
484 case CHAT_MSG_RAID:
485 {
486 // if player is in battleground, he cannot say to battleground members by /ra
487 Group* group = GetPlayer()->GetOriginalGroup();
488 if (!group)
489 {
490 group = GetPlayer()->GetGroup();
491 if (!group || group->isBGGroup() || !group->isRaidGroup())
492 return;
493 }
494
495 if (!sScriptMgr->CanPlayerUseChat(GetPlayer(), type, lang, msg, group))
496 {
497 return;
498 }
499
500 sScriptMgr->OnPlayerChat(GetPlayer(), type, lang, msg, group);
501
502 WorldPacket data;
503 ChatHandler::BuildChatPacket(data, CHAT_MSG_RAID, Language(lang), sender, nullptr, msg);
504 group->BroadcastPacket(&data, false);
505 }
506 break;
508 {
509 // if player is in battleground, he cannot say to battleground members by /ra
510 Group* group = GetPlayer()->GetOriginalGroup();
511 if (!group)
512 {
513 group = GetPlayer()->GetGroup();
514 if (!group || group->isBGGroup() || !group->isRaidGroup() || !group->IsLeader(sender->GetGUID()))
515 return;
516 }
517
518 if (!sScriptMgr->CanPlayerUseChat(GetPlayer(), type, lang, msg, group))
519 {
520 return;
521 }
522
523 sScriptMgr->OnPlayerChat(GetPlayer(), type, lang, msg, group);
524
525 WorldPacket data;
526 ChatHandler::BuildChatPacket(data, CHAT_MSG_RAID_LEADER, Language(lang), sender, nullptr, msg);
527 group->BroadcastPacket(&data, false);
528 }
529 break;
531 {
532 Group* group = GetPlayer()->GetGroup();
533 if (!group || !group->isRaidGroup() || !(group->IsLeader(GetPlayer()->GetGUID()) || group->IsAssistant(GetPlayer()->GetGUID())) || group->isBGGroup())
534 return;
535
536 if (!sScriptMgr->CanPlayerUseChat(GetPlayer(), type, lang, msg, group))
537 {
538 return;
539 }
540
541 sScriptMgr->OnPlayerChat(GetPlayer(), type, lang, msg, group);
542
543 // In battleground, raid warning is sent only to players in battleground - code is ok
544 WorldPacket data;
545 ChatHandler::BuildChatPacket(data, CHAT_MSG_RAID_WARNING, Language(lang), sender, nullptr, msg);
546 group->BroadcastPacket(&data, false);
547 }
548 break;
550 {
551 //battleground raid is always in Player->GetGroup(), never in GetOriginalGroup()
552 Group* group = GetPlayer()->GetGroup();
553 if (!group || !group->isBGGroup())
554 return;
555
556 if (!sScriptMgr->CanPlayerUseChat(GetPlayer(), type, lang, msg, group))
557 {
558 return;
559 }
560
561 sScriptMgr->OnPlayerChat(GetPlayer(), type, lang, msg, group);
562
563 WorldPacket data;
564 ChatHandler::BuildChatPacket(data, CHAT_MSG_BATTLEGROUND, Language(lang), sender, nullptr, msg);
565 group->BroadcastPacket(&data, false);
566 }
567 break;
569 {
570 // battleground raid is always in Player->GetGroup(), never in GetOriginalGroup()
571 Group* group = GetPlayer()->GetGroup();
572 if (!group || !group->isBGGroup() || !group->IsLeader(GetPlayer()->GetGUID()))
573 return;
574
575 if (!sScriptMgr->CanPlayerUseChat(GetPlayer(), type, lang, msg, group))
576 {
577 return;
578 }
579
580 sScriptMgr->OnPlayerChat(GetPlayer(), type, lang, msg, group);
581
582 WorldPacket data;
583 ChatHandler::BuildChatPacket(data, CHAT_MSG_BATTLEGROUND_LEADER, Language(lang), sender, nullptr, msg);
584 group->BroadcastPacket(&data, false);
585 }
586 break;
587 case CHAT_MSG_CHANNEL:
588 {
590 {
591 if (sender->GetLevel() < sWorld->getIntConfig(CONFIG_CHAT_CHANNEL_LEVEL_REQ))
592 {
594 return;
595 }
596 }
597
598 if (ChannelMgr* cMgr = ChannelMgr::forTeam(sender->GetTeamId()))
599 {
600 if (Channel* chn = cMgr->GetChannel(channel, sender))
601 {
602 if (!sScriptMgr->CanPlayerUseChat(sender, type, lang, msg, chn))
603 {
604 return;
605 }
606
607 sScriptMgr->OnPlayerChat(sender, type, lang, msg, chn);
608
609 chn->Say(sender->GetGUID(), msg.c_str(), lang);
610 }
611 }
612 }
613 break;
614 case CHAT_MSG_AFK:
615 {
616 if (!sender->IsInCombat())
617 {
618 if (sender->isAFK()) // Already AFK
619 {
620 if (msg.empty())
621 sender->ToggleAFK(); // Remove AFK
622 else
623 sender->autoReplyMsg = msg; // Update message
624 }
625 else // New AFK mode
626 {
627 sender->autoReplyMsg = msg.empty() ? GetAcoreString(LANG_PLAYER_AFK_DEFAULT) : msg;
628
629 if (sender->isDND())
630 sender->ToggleDND();
631
632 sender->ToggleAFK();
633 }
634
635 if (!sScriptMgr->CanPlayerUseChat(sender, type, lang, msg))
636 {
637 return;
638 }
639
640 sScriptMgr->OnPlayerChat(sender, type, lang, msg);
641 }
642 break;
643 }
644 case CHAT_MSG_DND:
645 {
646 if (sender->isDND()) // Already DND
647 {
648 if (msg.empty())
649 sender->ToggleDND(); // Remove DND
650 else
651 sender->autoReplyMsg = msg; // Update message
652 }
653 else // New DND mode
654 {
655 sender->autoReplyMsg = msg.empty() ? GetAcoreString(LANG_PLAYER_DND_DEFAULT) : msg;
656
657 if (sender->isAFK())
658 sender->ToggleAFK();
659
660 sender->ToggleDND();
661 }
662
663 if (!sScriptMgr->CanPlayerUseChat(sender, type, lang, msg))
664 {
665 return;
666 }
667
668 sScriptMgr->OnPlayerChat(sender, type, lang, msg);
669
670 break;
671 }
672 default:
673 LOG_ERROR("network.opcode", "CHAT: unknown message type {}, lang: {}", type, lang);
674 break;
675 }
676}
@ SEC_PLAYER
Definition: Common.h:57
std::string secsToTimeString(uint64 timeInSecs, bool shortText)
Definition: Util.cpp:73
bool isNasty(uint8 c)
Definition: ChatHandler.cpp:44
LanguageDesc const * GetLanguageDescByID(uint32 lang)
Definition: ObjectMgr.cpp:251
@ CONFIG_CHAT_CHANNEL_LEVEL_REQ
Definition: IWorld.h:290
@ CONFIG_CHAT_WHISPER_LEVEL_REQ
Definition: IWorld.h:291
@ CONFIG_CHAT_TIME_MUTE_FIRST_LOGIN
Definition: IWorld.h:294
@ CONFIG_CHAT_SAY_LEVEL_REQ
Definition: IWorld.h:292
@ CONFIG_ALLOW_TWO_SIDE_INTERACTION_CHAT
Definition: IWorld.h:73
@ CONFIG_CHAT_MUTE_FIRST_LOGIN
Definition: IWorld.h:102
@ CONFIG_CHAT_FAKE_MESSAGE_PREVENTING
Definition: IWorld.h:101
@ CONFIG_ADDON_CHANNEL
Definition: IWorld.h:67
@ LANG_SAY_REQ
Definition: Language.h:1151
@ LANG_GM_SILENCE
Definition: Language.h:1166
@ LANG_UNKNOWN_LANGUAGE
Definition: Language.h:742
@ LANG_NOT_LEARNED_LANGUAGE
Definition: Language.h:743
@ LANG_WHISPER_REQ
Definition: Language.h:1152
@ LANG_WAIT_BEFORE_SPEAKING
Definition: Language.h:670
@ LANG_PLAYER_AFK_DEFAULT
Definition: Language.h:675
@ LANG_MUTED_PLAYER
Definition: Language.h:1311
@ LANG_PLAYER_DND_DEFAULT
Definition: Language.h:674
@ LANG_CHANNEL_REQ
Definition: Language.h:1153
@ SPELL_AURA_COMPREHEND_LANGUAGE
Definition: SpellAuraDefines.h:307
@ SPELL_AURA_MOD_LANGUAGE
Definition: SpellAuraDefines.h:138
ChatMsg
Definition: SharedDefines.h:3150
@ CHAT_MSG_RAID_WARNING
Definition: SharedDefines.h:3192
@ CHAT_MSG_RAID
Definition: SharedDefines.h:3155
@ CHAT_MSG_TEXT_EMOTE
Definition: SharedDefines.h:3163
@ CHAT_MSG_SAY
Definition: SharedDefines.h:3153
@ CHAT_MSG_PARTY_LEADER
Definition: SharedDefines.h:3203
@ CHAT_MSG_RAID_LEADER
Definition: SharedDefines.h:3191
@ CHAT_MSG_DND
Definition: SharedDefines.h:3176
@ CHAT_MSG_YELL
Definition: SharedDefines.h:3158
@ CHAT_MSG_PARTY
Definition: SharedDefines.h:3154
@ CHAT_MSG_WHISPER
Definition: SharedDefines.h:3159
@ CHAT_MSG_EMOTE
Definition: SharedDefines.h:3162
@ CHAT_MSG_GUILD
Definition: SharedDefines.h:3156
@ CHAT_MSG_OFFICER
Definition: SharedDefines.h:3157
@ CHAT_MSG_AFK
Definition: SharedDefines.h:3175
@ CHAT_MSG_ADDON
Definition: SharedDefines.h:3151
@ CHAT_MSG_BATTLEGROUND
Definition: SharedDefines.h:3196
@ CHAT_MSG_BATTLEGROUND_LEADER
Definition: SharedDefines.h:3197
@ CHAT_MSG_CHANNEL
Definition: SharedDefines.h:3169
Language
Definition: SharedDefines.h:734
@ LANG_ADDON
Definition: SharedDefines.h:753
#define MAX_CHAT_MSG_TYPE
Definition: SharedDefines.h:3206
Definition: Chat.h:279
bool CanSpeak() const
Definition: PlayerMisc.cpp:69
bool IsInWhisperWhiteList(ObjectGuid guid)
Definition: Player.cpp:15894
std::string autoReplyMsg
Definition: Player.h:1137
uint32 GetTotalPlayedTime()
Definition: Player.h:1186
bool HasSkill(uint32 skill) const
Definition: Player.cpp:5416
void ToggleAFK()
Definition: Player.cpp:1289
void UpdateSpeakTime(ChatFloodThrottle::Index index)
Definition: PlayerMisc.cpp:29
void AddWhisperWhiteList(ObjectGuid guid)
Definition: Player.h:2541
bool isAcceptWhispers() const
Definition: Player.h:1156
void Yell(std::string_view text, Language language, WorldObject const *=nullptr) override
Handles yelled message in regular chat based on declared language and in config pre-defined Range.
Definition: Player.cpp:9358
void Say(std::string_view text, Language language, WorldObject const *=nullptr) override
Handles said message in regular chat based on declared language and in config pre-defined Range.
Definition: Player.cpp:9338
void TextEmote(std::string_view text, WorldObject const *=nullptr, bool=false) override
Outputs an universal text which is supposed to be an action.
Definition: Player.cpp:9379
void Whisper(std::string_view text, Language language, Player *receiver, bool=false) override
Handles whispers from Addons and players based on sender, receiver's guid and language.
Definition: Player.cpp:9401
void ToggleDND()
Definition: Player.cpp:1298
@ ADDON
Definition: Player.h:2300
@ REGULAR
Definition: Player.h:2299
AuraEffectList const & GetAuraEffectsByType(AuraType type) const
Definition: Unit.h:1374
std::list< AuraEffect * > AuraEffectList
Definition: Unit.h:646
Definition: ObjectMgr.h:690
uint32 skill_id
Definition: ObjectMgr.h:693
void BroadcastPacket(WorldPacket const *packet, bool ignorePlayersInBGRaid, int group=-1, ObjectGuid ignore=ObjectGuid::Empty)
Definition: Group.cpp:1757
void SendPlayerNotFoundNotice(std::string const &name)
Definition: ChatHandler.cpp:823
void SendWrongFactionNotice()
Definition: ChatHandler.cpp:837
std::unique_ptr< Warden > _warden
Definition: WorldSession.h:1158

References _addonMessageReceiveCount, _player, _warden, Player::ChatFloodThrottle::ADDON, Player::AddWhisperWhiteList(), Player::autoReplyMsg, Group::BroadcastPacket(), ChatHandler::BuildChatPacket(), Player::CanSpeak(), CHAT_MSG_ADDON, CHAT_MSG_AFK, CHAT_MSG_BATTLEGROUND, CHAT_MSG_BATTLEGROUND_LEADER, CHAT_MSG_CHANNEL, CHAT_MSG_DND, CHAT_MSG_EMOTE, CHAT_MSG_GUILD, CHAT_MSG_OFFICER, CHAT_MSG_PARTY, CHAT_MSG_PARTY_LEADER, CHAT_MSG_RAID, CHAT_MSG_RAID_LEADER, CHAT_MSG_RAID_WARNING, CHAT_MSG_SAY, CHAT_MSG_TEXT_EMOTE, CHAT_MSG_WHISPER, CHAT_MSG_YELL, CONFIG_ADDON_CHANNEL, CONFIG_ALLOW_TWO_SIDE_INTERACTION_CHAT, CONFIG_ALLOW_TWO_SIDE_INTERACTION_GROUP, CONFIG_ALLOW_TWO_SIDE_INTERACTION_GUILD, CONFIG_CHAT_CHANNEL_LEVEL_REQ, CONFIG_CHAT_FAKE_MESSAGE_PREVENTING, CONFIG_CHAT_MUTE_FIRST_LOGIN, CONFIG_CHAT_SAY_LEVEL_REQ, CONFIG_CHAT_TIME_MUTE_FIRST_LOGIN, CONFIG_CHAT_WHISPER_LEVEL_REQ, ObjectAccessor::FindPlayerByName(), ChannelMgr::forTeam(), GetAcoreString(), Unit::GetAuraEffectsByType(), GameTime::GetGameTime(), Player::GetGroup(), Object::GetGUID(), GetLanguageDescByID(), Unit::GetLevel(), Group::GetMemberGroup(), WorldObject::GetName(), Player::GetOriginalGroup(), GetPlayer(), GetPlayerInfo(), GetSecurity(), Player::GetSession(), Player::GetTeamId(), GetTeamId(), Player::GetTotalPlayedTime(), Unit::HasAura(), Player::HasSkill(), Player::isAcceptWhispers(), Player::isAFK(), Unit::IsAlive(), Group::IsAssistant(), Group::isBGGroup(), Player::isDND(), Player::IsGameMaster(), Unit::IsInCombat(), Player::IsInWhisperWhiteList(), Group::IsLeader(), isNasty(), AccountMgr::IsPlayerAccount(), Group::isRaidGroup(), Player::IsSpectator(), LANG_ADDON, LANG_CHANNEL_REQ, LANG_GM_SILENCE, LANG_MUTED_PLAYER, LANG_NOT_LEARNED_LANGUAGE, LANG_PLAYER_AFK_DEFAULT, LANG_PLAYER_DND_DEFAULT, LANG_SAY_REQ, LANG_UNIVERSAL, LANG_UNKNOWN_LANGUAGE, LANG_WAIT_BEFORE_SPEAKING, LANG_WHISPER_REQ, LOG_ERROR, m_muteTime, MAX_CHAT_MSG_TYPE, MINUTE, normalizePlayerName(), ByteBuffer::ReadCString(), Player::ChatFloodThrottle::REGULAR, ByteBuffer::rfinish(), Player::Say(), SEC_PLAYER, secsToTimeString(), ChatHandler::SendNotification(), SendPlayerNotFoundNotice(), SendWrongFactionNotice(), sGuildMgr, LanguageDesc::skill_id, SPELL_AURA_COMPREHEND_LANGUAGE, SPELL_AURA_MOD_LANGUAGE, sScriptMgr, sWorld, Player::TextEmote(), Player::ToggleAFK(), Player::ToggleDND(), Player::UpdateSpeakTime(), ValidateHyperlinksAndMaybeKick(), Player::Whisper(), and Player::Yell().

Referenced by OpcodeTable::Initialize().

◆ HandleMinimapPingOpcode()

void WorldSession::HandleMinimapPingOpcode ( WorldPacket recvData)

error handling

526{
527 if (!GetPlayer()->GetGroup())
528 return;
529
530 float x, y;
531 recvData >> x;
532 recvData >> y;
533
535 /********************/
536
537 // everything's fine, do it
538 WorldPacket data(MSG_MINIMAP_PING, (8 + 4 + 4));
539 data << GetPlayer()->GetGUID();
540 data << float(x);
541 data << float(y);
542 GetPlayer()->GetGroup()->BroadcastPacket(&data, true, -1, GetPlayer()->GetGUID());
543}
@ MSG_MINIMAP_PING
Definition: Opcodes.h:499

References Group::BroadcastPacket(), Player::GetGroup(), Object::GetGUID(), GetPlayer(), and MSG_MINIMAP_PING.

Referenced by OpcodeTable::Initialize().

◆ HandleMirrorImageDataRequest()

void WorldSession::HandleMirrorImageDataRequest ( WorldPacket recvData)
665{
666 LOG_DEBUG("network", "WORLD: CMSG_GET_MIRRORIMAGE_DATA");
667 ObjectGuid guid;
668 recvData >> guid;
669
670 // Get unit for which data is needed by client
671 Unit* unit = ObjectAccessor::GetUnit(*_player, guid);
672 if (!unit)
673 return;
674
676 return;
677
678 // Get creator of the unit (SPELL_AURA_CLONE_CASTER does not stack)
679 Unit* creator = unit->GetAuraEffectsByType(SPELL_AURA_CLONE_CASTER).front()->GetCaster();
680 if (!creator)
681 return;
682
684 data << guid;
685 data << uint32(creator->GetDisplayId());
686 data << uint8(creator->getRace());
687 data << uint8(creator->getGender());
688 data << uint8(creator->getClass());
689
690 if (creator->IsPlayer())
691 {
692 Player* player = creator->ToPlayer();
693 data << uint8(player->GetByteValue(PLAYER_BYTES, 0)); // skin
694 data << uint8(player->GetByteValue(PLAYER_BYTES, 1)); // face
695 data << uint8(player->GetByteValue(PLAYER_BYTES, 2)); // hair
696 data << uint8(player->GetByteValue(PLAYER_BYTES, 3)); // haircolor
697 data << uint8(player->GetByteValue(PLAYER_BYTES_2, 0)); // facialhair
698 data << uint32(player->GetGuildId()); // unk
699
700 static EquipmentSlots const itemSlots[] =
701 {
714 };
715
716 // Display items in visible slots
717 for (EquipmentSlots const* itr = &itemSlots[0]; *itr != EQUIPMENT_SLOT_END; ++itr)
718 {
720 data << uint32(0);
721 else if (*itr == EQUIPMENT_SLOT_BACK && player->HasPlayerFlag(PLAYER_FLAGS_HIDE_CLOAK))
722 data << uint32(0);
723 else if (Item const* item = player->GetItemByPos(INVENTORY_SLOT_BAG_0, *itr))
724 {
725 uint32 displayInfoId = item->GetTemplate()->DisplayInfoID;
726
727 sScriptMgr->OnGlobalMirrorImageDisplayItem(item, displayInfoId);
728
729 data << uint32(displayInfoId);
730 }
731 else
732 data << uint32(0);
733 }
734 }
735 else
736 {
737 // Skip player data for creatures
738 data << uint8(0);
739 data << uint32(0);
740 data << uint32(0);
741 data << uint32(0);
742 data << uint32(0);
743 data << uint32(0);
744 data << uint32(0);
745 data << uint32(0);
746 data << uint32(0);
747 data << uint32(0);
748 data << uint32(0);
749 data << uint32(0);
750 data << uint32(0);
751 data << uint32(0);
752 }
753
754 SendPacket(&data);
755}
@ PLAYER_FLAGS_HIDE_CLOAK
Definition: Player.h:485
@ PLAYER_FLAGS_HIDE_HELM
Definition: Player.h:484
EquipmentSlots
Definition: Player.h:673
@ EQUIPMENT_SLOT_SHOULDERS
Definition: Player.h:677
@ EQUIPMENT_SLOT_BODY
Definition: Player.h:678
@ EQUIPMENT_SLOT_HANDS
Definition: Player.h:684
@ EQUIPMENT_SLOT_TABARD
Definition: Player.h:693
@ EQUIPMENT_SLOT_HEAD
Definition: Player.h:675
@ EQUIPMENT_SLOT_LEGS
Definition: Player.h:681
@ EQUIPMENT_SLOT_BACK
Definition: Player.h:689
@ EQUIPMENT_SLOT_WAIST
Definition: Player.h:680
@ EQUIPMENT_SLOT_FEET
Definition: Player.h:682
@ EQUIPMENT_SLOT_CHEST
Definition: Player.h:679
@ EQUIPMENT_SLOT_WRISTS
Definition: Player.h:683
@ SPELL_AURA_CLONE_CASTER
Definition: SpellAuraDefines.h:310
@ SMSG_MIRRORIMAGE_DATA
Definition: Opcodes.h:1056
uint8 GetByteValue(uint16 index, uint8 offset) const
Definition: Object.cpp:323
uint8 getClass() const
Definition: Unit.h:747
bool HasAuraType(AuraType auraType) const
Definition: Unit.cpp:5683

References _player, EQUIPMENT_SLOT_BACK, EQUIPMENT_SLOT_BODY, EQUIPMENT_SLOT_CHEST, EQUIPMENT_SLOT_END, EQUIPMENT_SLOT_FEET, EQUIPMENT_SLOT_HANDS, EQUIPMENT_SLOT_HEAD, EQUIPMENT_SLOT_LEGS, EQUIPMENT_SLOT_SHOULDERS, EQUIPMENT_SLOT_TABARD, EQUIPMENT_SLOT_WAIST, EQUIPMENT_SLOT_WRISTS, Unit::GetAuraEffectsByType(), Object::GetByteValue(), Unit::getClass(), Unit::GetDisplayId(), Unit::getGender(), Player::GetGuildId(), Player::GetItemByPos(), Unit::getRace(), ObjectAccessor::GetUnit(), Unit::HasAuraType(), Player::HasPlayerFlag(), INVENTORY_SLOT_BAG_0, Object::IsPlayer(), LOG_DEBUG, PLAYER_BYTES, PLAYER_BYTES_2, PLAYER_FLAGS_HIDE_CLOAK, PLAYER_FLAGS_HIDE_HELM, SendPacket(), SMSG_MIRRORIMAGE_DATA, SPELL_AURA_CLONE_CASTER, sScriptMgr, and Object::ToPlayer().

Referenced by OpcodeTable::Initialize().

◆ HandleMountSpecialAnimOpcode()

void WorldSession::HandleMountSpecialAnimOpcode ( WorldPacket recvdata)
754{
756 data << GetPlayer()->GetGUID();
757
758 GetPlayer()->SendMessageToSet(&data, false);
759}
@ SMSG_MOUNTSPECIAL_ANIM
Definition: Opcodes.h:400
void SendMessageToSet(WorldPacket const *data, bool self) const override
Definition: Player.cpp:5656

References Object::GetGUID(), GetPlayer(), Player::SendMessageToSet(), and SMSG_MOUNTSPECIAL_ANIM.

Referenced by OpcodeTable::Initialize().

◆ HandleMoveHoverAck()

void WorldSession::HandleMoveHoverAck ( WorldPacket recvData)
797{
798 LOG_DEBUG("network", "CMSG_MOVE_HOVER_ACK");
799
800 ObjectGuid guid;
801 recvData >> guid.ReadAsPacked();
802
803 recvData.read_skip<uint32>(); // unk
804
805 MovementInfo movementInfo;
806 movementInfo.guid = guid;
807 ReadMovementInfo(recvData, &movementInfo);
808
809 recvData.read_skip<uint32>(); // unk2
810}

References MovementInfo::guid, LOG_DEBUG, ByteBuffer::read_skip(), ObjectGuid::ReadAsPacked(), and ReadMovementInfo().

Referenced by OpcodeTable::Initialize().

◆ HandleMoveKnockBackAck()

void WorldSession::HandleMoveKnockBackAck ( WorldPacket recvPacket)
762{
763 LOG_DEBUG("network", "CMSG_MOVE_KNOCK_BACK_ACK");
764
765 ObjectGuid guid;
766 recvData >> guid.ReadAsPacked();
767
768 // pussywizard: typical check for incomming movement packets
770 {
771 recvData.rfinish(); // prevent warnings spam
772 return;
773 }
774
775 recvData.read_skip<uint32>(); // unk
776
777 MovementInfo movementInfo;
778 movementInfo.guid = guid;
779 ReadMovementInfo(recvData, &movementInfo);
780
781 _player->m_mover->m_movementInfo = movementInfo;
782
784 data << guid.WriteAsPacked();
786 _player->SetCanTeleport(true);
787 // knockback specific info
788 data << movementInfo.jump.sinAngle;
789 data << movementInfo.jump.cosAngle;
790 data << movementInfo.jump.xyspeed;
791 data << movementInfo.jump.zspeed;
792
793 _player->SendMessageToSet(&data, false);
794}
@ MSG_MOVE_KNOCK_BACK
Definition: Opcodes.h:271
void BuildMovementPacket(ByteBuffer *data) const
Definition: Unit.cpp:19877

References _player, Unit::BuildMovementPacket(), Object::GetGUID(), MovementInfo::guid, Unit::IsDuringRemoveFromWorld(), Object::IsInWorld(), LOG_DEBUG, WorldObject::m_movementInfo, Player::m_mover, MSG_MOVE_KNOCK_BACK, ByteBuffer::read_skip(), ObjectGuid::ReadAsPacked(), ReadMovementInfo(), ByteBuffer::rfinish(), Player::SendMessageToSet(), Player::SetCanTeleport(), and ObjectGuid::WriteAsPacked().

Referenced by OpcodeTable::Initialize().

◆ HandleMovementOpcodes()

void WorldSession::HandleMovementOpcodes ( WorldPacket recvPacket)
335{
336 uint16 opcode = recvData.GetOpcode();
337
338 Unit* mover = _player->m_mover;
339
340 ASSERT(mover); // there must always be a mover
341
342 Player* plrMover = mover->ToPlayer();
343
344 // ignore, waiting processing in WorldSession::HandleMoveWorldportAckOpcode and WorldSession::HandleMoveTeleportAck
345 if (plrMover && plrMover->IsBeingTeleported())
346 {
347 recvData.rfinish(); // prevent warnings spam
348 return;
349 }
350
351 /* extract packet */
352 ObjectGuid guid;
353 recvData >> guid.ReadAsPacked();
354
355 // prevent tampered movement data
356 if (!guid || guid != mover->GetGUID())
357 {
358 recvData.rfinish(); // prevent warnings spam
359 return;
360 }
361
362 // pussywizard: typical check for incomming movement packets | prevent tampered movement data
363 if (!mover || !(mover->IsInWorld()) || mover->IsDuringRemoveFromWorld() || guid != mover->GetGUID())
364 {
365 recvData.rfinish(); // prevent warnings spam
366 return;
367 }
368
369 MovementInfo movementInfo;
370 movementInfo.guid = guid;
371 ReadMovementInfo(recvData, &movementInfo);
372
373 // Stop emote on move
374 if (Player* plrMover = mover->ToPlayer())
375 {
377 {
379 }
380 }
381
382 if (!movementInfo.pos.IsPositionValid())
383 {
384 if (plrMover)
385 {
386 sScriptMgr->AnticheatUpdateMovementInfo(plrMover, movementInfo);
387 }
388
389 recvData.rfinish(); // prevent warnings spam
390 return;
391 }
392
393 if (!mover->movespline->Finalized())
394 {
395 recvData.rfinish(); // prevent warnings spam
396 return;
397 }
398
399 // Xinef: do not allow to move with UNIT_FLAG_DISABLE_MOVE
401 {
402 // Xinef: skip moving packets
404 {
405 if (plrMover)
406 {
407 sScriptMgr->AnticheatUpdateMovementInfo(plrMover, movementInfo);
408 }
409 return;
410 }
411 movementInfo.pos.Relocate(mover->GetPositionX(), mover->GetPositionY(), mover->GetPositionZ());
412
413 if (mover->IsCreature())
414 {
415 movementInfo.transport.guid = mover->m_movementInfo.transport.guid;
417 movementInfo.transport.seat = mover->m_movementInfo.transport.seat;
418 }
419 }
420
422 {
423 // We were teleported, skip packets that were broadcast before teleport
424 if (movementInfo.pos.GetExactDist2d(mover) > SIZE_OF_GRIDS)
425 {
426 if (plrMover)
427 {
428 sScriptMgr->AnticheatUpdateMovementInfo(plrMover, movementInfo);
429 //LOG_INFO("anticheat", "MovementHandler:: 2 We were teleported, skip packets that were broadcast before teleport");
430 }
431 recvData.rfinish(); // prevent warnings spam
432 return;
433 }
434
435 if (!Acore::IsValidMapCoord(movementInfo.pos.GetPositionX() + movementInfo.transport.pos.GetPositionX(), movementInfo.pos.GetPositionY() + movementInfo.transport.pos.GetPositionY(),
436 movementInfo.pos.GetPositionZ() + movementInfo.transport.pos.GetPositionZ(), movementInfo.pos.GetOrientation() + movementInfo.transport.pos.GetOrientation()))
437 {
438 if (plrMover)
439 {
440 sScriptMgr->AnticheatUpdateMovementInfo(plrMover, movementInfo);
441 }
442
443 recvData.rfinish(); // prevent warnings spam
444 return;
445 }
446
447 // if we boarded a transport, add us to it
448 if (plrMover)
449 {
450 if (!plrMover->GetTransport())
451 {
452 if (Transport* transport = plrMover->GetMap()->GetTransport(movementInfo.transport.guid))
453 {
454 plrMover->m_transport = transport;
455 transport->AddPassenger(plrMover);
456 }
457 }
458 else if (plrMover->GetTransport()->GetGUID() != movementInfo.transport.guid)
459 {
460 bool foundNewTransport = false;
461 plrMover->m_transport->RemovePassenger(plrMover);
462 if (Transport* transport = plrMover->GetMap()->GetTransport(movementInfo.transport.guid))
463 {
464 foundNewTransport = true;
465 plrMover->m_transport = transport;
466 transport->AddPassenger(plrMover);
467 }
468
469 if (!foundNewTransport)
470 {
471 plrMover->m_transport = nullptr;
472 movementInfo.transport.Reset();
473 }
474 }
475 }
476
477 if (!mover->GetTransport() && !mover->GetVehicle())
478 {
479 GameObject* go = mover->GetMap()->GetGameObject(movementInfo.transport.guid);
480 if (!go || go->GetGoType() != GAMEOBJECT_TYPE_TRANSPORT)
481 {
483 }
484 }
485 }
486 else if (plrMover && plrMover->GetTransport()) // if we were on a transport, leave
487 {
488 sScriptMgr->AnticheatSetUnderACKmount(plrMover); // just for safe
489
490 plrMover->m_transport->RemovePassenger(plrMover);
491 plrMover->m_transport = nullptr;
492 movementInfo.transport.Reset();
493 }
494
495 // fall damage generation (ignore in flight case that can be triggered also at lags in moment teleportation to another map).
496 if (opcode == MSG_MOVE_FALL_LAND && plrMover && !plrMover->IsInFlight())
497 {
498 plrMover->HandleFall(movementInfo);
499
500 sScriptMgr->AnticheatSetJumpingbyOpcode(plrMover, false);
501 }
502
503 // interrupt parachutes upon falling or landing in water
504 if (opcode == MSG_MOVE_FALL_LAND || opcode == MSG_MOVE_START_SWIM)
505 {
507
508 if (plrMover)
509 {
510 sScriptMgr->AnticheatSetJumpingbyOpcode(plrMover, false);
511 }
512 }
513
514 if (plrMover && ((movementInfo.flags & MOVEMENTFLAG_SWIMMING) != 0) != plrMover->IsInWater())
515 {
516 // now client not include swimming flag in case jumping under water
517 plrMover->SetInWater(!plrMover->IsInWater() || plrMover->GetMap()->IsUnderWater(plrMover->GetPhaseMask(), movementInfo.pos.GetPositionX(),
518 movementInfo.pos.GetPositionY(), movementInfo.pos.GetPositionZ(), plrMover->GetCollisionHeight()));
519 }
520
521 if (plrMover)//Hook for OnPlayerMove
522 {
523 sScriptMgr->OnPlayerMove(plrMover, movementInfo, opcode);
524 }
525
526 bool jumpopcode = false;
527 if (opcode == MSG_MOVE_JUMP)
528 {
529 jumpopcode = true;
530 if (plrMover && !sScriptMgr->AnticheatHandleDoubleJump(plrMover, mover))
531 {
532 plrMover->GetSession()->KickPlayer();
533 return;
534 }
535 }
536
537 /* start some hack detection */
538 if (plrMover && !sScriptMgr->AnticheatCheckMovementInfo(plrMover, movementInfo, mover, jumpopcode))
539 {
540 plrMover->GetSession()->KickPlayer();
541 return;
542 }
543
544 /* process position-change */
545 WorldPacket data(opcode, recvData.size());
546 int64 movementTime = (int64)movementInfo.time + _timeSyncClockDelta;
547 if (_timeSyncClockDelta == 0 || movementTime < 0 || movementTime > 0xFFFFFFFF)
548 {
549 LOG_INFO("misc", "The computed movement time using clockDelta is erronous. Using fallback instead");
550 movementInfo.time = getMSTime();
551 }
552 else
553 {
554 movementInfo.time = (uint32) movementTime;
555 }
556
557 movementInfo.guid = mover->GetGUID();
558 WriteMovementInfo(&data, &movementInfo);
559 mover->SendMessageToSet(&data, _player);
560
561 mover->m_movementInfo = movementInfo;
562
563 // Some vehicles allow the passenger to turn by himself
564 if (Vehicle* vehicle = mover->GetVehicle())
565 {
566 if (VehicleSeatEntry const* seat = vehicle->GetSeatForPassenger(mover))
567 {
568 if (seat->m_flags & VEHICLE_SEAT_FLAG_ALLOW_TURNING && movementInfo.pos.GetOrientation() != mover->GetOrientation())
569 {
570 mover->SetOrientation(movementInfo.pos.GetOrientation());
572 }
573 }
574
575 return;
576 }
577
578 mover->UpdatePosition(movementInfo.pos);
579
580 if (plrMover) // nothing is charmed, or player charmed
581 {
582 if (plrMover->IsSitState() && (movementInfo.flags & (MOVEMENTFLAG_MASK_MOVING | MOVEMENTFLAG_MASK_TURNING)))
584
585 plrMover->UpdateFallInformationIfNeed(movementInfo, opcode);
586
587 if (movementInfo.pos.GetPositionZ() < plrMover->GetMap()->GetMinHeight(movementInfo.pos.GetPositionX(), movementInfo.pos.GetPositionY()))
588 if (!plrMover->GetBattleground() || !plrMover->GetBattleground()->HandlePlayerUnderMap(_player))
589 {
590 if (plrMover->IsAlive())
591 {
593 plrMover->EnvironmentalDamage(DAMAGE_FALL_TO_VOID, GetPlayer()->GetMaxHealth());
594 // player can be alive if GM
595 if (plrMover->IsAlive())
596 plrMover->KillPlayer();
597 }
598 else if (!plrMover->HasPlayerFlag(PLAYER_FLAGS_IS_OUT_OF_BOUNDS))
599 {
600 GraveyardStruct const* grave = sGraveyard->GetClosestGraveyard(plrMover, plrMover->GetTeamId());
601 if (grave)
602 {
603 plrMover->TeleportTo(grave->Map, grave->x, grave->y, grave->z, plrMover->GetOrientation());
604 plrMover->Relocate(grave->x, grave->y, grave->z, plrMover->GetOrientation());
605 }
606 }
607 }
608 }
609}
#define SIZE_OF_GRIDS
Definition: MapDefines.h:25
uint32 getMSTime()
Definition: Timer.h:103
#define sGraveyard
Definition: GameGraveyard.h:75
@ MOVEMENTFLAG_ONTRANSPORT
Definition: UnitDefines.h:353
@ MOVEMENTFLAG_MASK_MOVING
Definition: UnitDefines.h:377
@ MOVEMENTFLAG_MASK_TURNING
Definition: UnitDefines.h:382
@ MOVEMENTFLAG_SWIMMING
Definition: UnitDefines.h:365
@ UNIT_FLAG_DISABLE_MOVE
Definition: UnitDefines.h:231
@ UNIT_NPC_EMOTESTATE
Definition: UpdateFields.h:140
@ DAMAGE_FALL_TO_VOID
Definition: Player.h:840
@ PLAYER_FLAGS_IS_OUT_OF_BOUNDS
Definition: Player.h:488
@ AURA_INTERRUPT_FLAG_TURNING
Definition: SpellDefines.h:47
@ AURA_INTERRUPT_FLAG_LANDING
Definition: SpellDefines.h:68
@ GAMEOBJECT_TYPE_TRANSPORT
Definition: SharedDefines.h:1571
@ VEHICLE_SEAT_FLAG_ALLOW_TURNING
Definition: DBCEnums.h:454
@ MSG_MOVE_START_SWIM
Definition: Opcodes.h:232
@ MSG_MOVE_JUMP
Definition: Opcodes.h:217
@ MSG_MOVE_FALL_LAND
Definition: Opcodes.h:231
bool IsValidMapCoord(float c)
Definition: GridDefines.h:216
virtual bool HandlePlayerUnderMap(Player *)
Definition: Battleground.h:564
uint32 time
Definition: Object.h:282
void RemoveMovementFlag(uint32 flag)
Definition: Object.h:333
uint32 flags
Definition: Object.h:279
bool HasMovementFlag(uint32 flag) const
Definition: Object.h:334
Position pos
Definition: Object.h:281
void Reset()
Definition: Object.h:287
ObjectGuid guid
Definition: Object.h:296
Position pos
Definition: Object.h:297
uint32 GetPhaseMask() const
Definition: Object.h:446
virtual void SendMessageToSet(WorldPacket const *data, bool self) const
Definition: Object.cpp:2080
Transport * m_transport
Definition: Object.h:654
float GetExactDist2d(const float x, const float y) const
Definition: Position.h:166
bool IsPositionValid() const
Definition: Position.cpp:175
void SetOrientation(float orientation)
Definition: Position.h:112
void Relocate(float x, float y)
Definition: Position.h:73
void HandleFall(MovementInfo const &movementInfo)
Definition: Player.cpp:13850
void SetPlayerFlag(PlayerFlags flags)
Definition: Player.h:1109
uint32 EnvironmentalDamage(EnviromentalDamage type, uint32 damage)
Definition: Player.cpp:754
void KillPlayer()
Definition: Player.cpp:4536
void SetInWater(bool apply)
Definition: Player.cpp:2162
bool IsInWater() const override
Definition: Player.h:1119
void UpdateFallInformationIfNeed(MovementInfo const &minfo, uint16 opcode)
Definition: PlayerUpdates.cpp:2136
bool IsBeingTeleported() const
Definition: Player.h:2072
Definition: Transport.h:29
virtual void RemovePassenger(WorldObject *passenger, bool withAll=false)=0
virtual void AddPassenger(WorldObject *passenger, bool withAll=false)=0
Movement::MoveSpline * movespline
Definition: Unit.h:1835
float GetCollisionHeight() const override
Return collision height sent to client.
Definition: Unit.cpp:21081
bool HasUnitFlag(UnitFlags flags) const
Definition: Unit.h:682
virtual bool UpdatePosition(float x, float y, float z, float ang, bool teleport=false)
Definition: Unit.cpp:20002
void SetUInt32Value(uint16 index, uint32 value)
Definition: Unit.cpp:21291
bool IsSitState() const
Definition: Unit.cpp:16676
bool IsUnderWater(uint32 phaseMask, float x, float y, float z, float collisionHeight) const
Definition: Map.cpp:2506
float GetMinHeight(float x, float y) const
Definition: Map.cpp:2085
Transport * GetTransport(ObjectGuid const guid)
Definition: Map.cpp:3329
Definition: GameGraveyard.h:28
float z
Definition: GameGraveyard.h:33
float x
Definition: GameGraveyard.h:31
float y
Definition: GameGraveyard.h:32
uint32 Map
Definition: GameGraveyard.h:30
bool Finalized() const
Definition: MoveSpline.h:116
void WriteMovementInfo(WorldPacket *data, MovementInfo *mi)
Definition: WorldSession.cpp:1073

References _player, _timeSyncClockDelta, Transport::AddPassenger(), ASSERT, AURA_INTERRUPT_FLAG_LANDING, AURA_INTERRUPT_FLAG_TURNING, DAMAGE_FALL_TO_VOID, EMOTE_ONESHOT_NONE, Player::EnvironmentalDamage(), Movement::MoveSpline::Finalized(), MovementInfo::flags, GAMEOBJECT_TYPE_TRANSPORT, Player::GetBattleground(), Unit::GetCollisionHeight(), Position::GetExactDist2d(), Map::GetGameObject(), GameObject::GetGoType(), Object::GetGUID(), WorldObject::GetMap(), Map::GetMinHeight(), getMSTime(), WorldPacket::GetOpcode(), Position::GetOrientation(), WorldObject::GetPhaseMask(), GetPlayer(), Position::GetPositionX(), Position::GetPositionY(), Position::GetPositionZ(), Player::GetSession(), Player::GetTeamId(), WorldObject::GetTransport(), Map::GetTransport(), Object::GetUInt32Value(), Unit::GetVehicle(), MovementInfo::guid, MovementInfo::TransportInfo::guid, Player::HandleFall(), Battleground::HandlePlayerUnderMap(), MovementInfo::HasMovementFlag(), Player::HasPlayerFlag(), Unit::HasUnitFlag(), Unit::IsAlive(), Player::IsBeingTeleported(), Object::IsCreature(), Unit::IsDuringRemoveFromWorld(), Unit::IsInFlight(), Player::IsInWater(), Object::IsInWorld(), Position::IsPositionValid(), Unit::IsSitState(), Map::IsUnderWater(), Acore::IsValidMapCoord(), KickPlayer(), Player::KillPlayer(), LOG_INFO, WorldObject::m_movementInfo, Player::m_mover, WorldObject::m_transport, GraveyardStruct::Map, MOVEMENTFLAG_MASK_MOVING, MOVEMENTFLAG_MASK_TURNING, MOVEMENTFLAG_ONTRANSPORT, MOVEMENTFLAG_SWIMMING, Unit::movespline, MSG_MOVE_FALL_LAND, MSG_MOVE_JUMP, MSG_MOVE_START_SWIM, PLAYER_FLAGS_IS_OUT_OF_BOUNDS, MovementInfo::pos, MovementInfo::TransportInfo::pos, ObjectGuid::ReadAsPacked(), ReadMovementInfo(), Position::Relocate(), Unit::RemoveAurasWithInterruptFlags(), MovementInfo::RemoveMovementFlag(), Transport::RemovePassenger(), MovementInfo::TransportInfo::Reset(), ByteBuffer::rfinish(), MovementInfo::TransportInfo::seat, WorldObject::SendMessageToSet(), Player::SetInWater(), Position::SetOrientation(), Player::SetPlayerFlag(), Unit::SetStandState(), Unit::SetUInt32Value(), sGraveyard, ByteBuffer::size(), SIZE_OF_GRIDS, sScriptMgr, Player::TeleportTo(), MovementInfo::time, Object::ToPlayer(), MovementInfo::transport, UNIT_FLAG_DISABLE_MOVE, UNIT_NPC_EMOTESTATE, UNIT_STAND_STATE_STAND, Player::UpdateFallInformationIfNeed(), Unit::UpdatePosition(), VEHICLE_SEAT_FLAG_ALLOW_TURNING, WriteMovementInfo(), GraveyardStruct::x, GraveyardStruct::y, and GraveyardStruct::z.

Referenced by HandleClientCastFlags(), HandleUpdateMissileTrajectory(), and OpcodeTable::Initialize().

◆ HandleMoveNotActiveMover()

void WorldSession::HandleMoveNotActiveMover ( WorldPacket recvData)
733{
734 LOG_DEBUG("network", "WORLD: Recvd CMSG_MOVE_NOT_ACTIVE_MOVER");
735
736 ObjectGuid old_mover_guid;
737 recvData >> old_mover_guid.ReadAsPacked();
738
739 // pussywizard: typical check for incomming movement packets
741 {
742 recvData.rfinish(); // prevent warnings spam
743 return;
744 }
745
746 MovementInfo mi;
747 mi.guid = old_mover_guid;
748 ReadMovementInfo(recvData, &mi);
749
751}

References _player, Object::GetGUID(), MovementInfo::guid, Unit::IsDuringRemoveFromWorld(), Object::IsInWorld(), LOG_DEBUG, WorldObject::m_movementInfo, Player::m_mover, ObjectGuid::ReadAsPacked(), ReadMovementInfo(), and ByteBuffer::rfinish().

Referenced by OpcodeTable::Initialize().

◆ HandleMoveRootAck()

void WorldSession::HandleMoveRootAck ( WorldPacket recvPacket)
955{
956 ObjectGuid guid;
957 recvData >> guid.ReadAsPacked();
958
959 Unit* mover = _player->m_mover;
960 if (!mover || guid != mover->GetGUID())
961 {
962 recvData.rfinish(); // prevent warnings spam
963 return;
964 }
965
966 uint32 movementCounter;
967 recvData >> movementCounter;
968
969 MovementInfo movementInfo;
970 movementInfo.guid = guid;
971 ReadMovementInfo(recvData, &movementInfo);
972
973 /* process position-change */
974 int64 movementTime = (int64) movementInfo.time + _timeSyncClockDelta;
975 if (_timeSyncClockDelta == 0 || movementTime < 0 || movementTime > 0xFFFFFFFF)
976 {
977 LOG_INFO("misc", "The computed movement time using clockDelta is erronous. Using fallback instead");
978 movementInfo.time = getMSTime();
979 }
980 else
981 {
982 movementInfo.time = (uint32)movementTime;
983 }
984
985 movementInfo.guid = mover->GetGUID();
986 mover->m_movementInfo = movementInfo;
987 mover->UpdatePosition(movementInfo.pos);
988
989 WorldPacket data(MSG_MOVE_ROOT, 64);
990 WriteMovementInfo(&data, &movementInfo);
991 mover->SendMessageToSet(&data, _player);
992}
@ MSG_MOVE_ROOT
Definition: Opcodes.h:266

References _player, _timeSyncClockDelta, Object::GetGUID(), getMSTime(), MovementInfo::guid, LOG_INFO, WorldObject::m_movementInfo, Player::m_mover, MSG_MOVE_ROOT, MovementInfo::pos, ObjectGuid::ReadAsPacked(), ReadMovementInfo(), ByteBuffer::rfinish(), WorldObject::SendMessageToSet(), MovementInfo::time, Unit::UpdatePosition(), and WriteMovementInfo().

Referenced by OpcodeTable::Initialize().

◆ HandleMoveSetCanFlyAckOpcode()

void WorldSession::HandleMoveSetCanFlyAckOpcode ( WorldPacket recvData)
1560{
1561 // fly mode on/off
1562 LOG_DEBUG("network", "WORLD: CMSG_MOVE_SET_CAN_FLY_ACK");
1563
1564 ObjectGuid guid;
1565 recv_data >> guid.ReadAsPacked();
1566
1567 if (!_player)
1568 {
1569 recv_data.rfinish(); // prevent warnings spam
1570 return;
1571 }
1572
1573 recv_data.read_skip<uint32>(); // unk
1574
1575 MovementInfo movementInfo;
1576 movementInfo.guid = guid;
1577 ReadMovementInfo(recv_data, &movementInfo);
1578
1579 recv_data.read_skip<float>(); // unk2
1580
1581 sScriptMgr->AnticheatSetCanFlybyServer(_player, movementInfo.HasMovementFlag(MOVEMENTFLAG_CAN_FLY));
1582
1583 _player->m_mover->m_movementInfo.flags = movementInfo.GetMovementFlags();
1584}
@ MOVEMENTFLAG_CAN_FLY
Definition: UnitDefines.h:368

References _player, MovementInfo::flags, MovementInfo::guid, LOG_DEBUG, WorldObject::m_movementInfo, Player::m_mover, MOVEMENTFLAG_CAN_FLY, ByteBuffer::read_skip(), ObjectGuid::ReadAsPacked(), ReadMovementInfo(), ByteBuffer::rfinish(), and sScriptMgr.

Referenced by OpcodeTable::Initialize().

◆ HandleMoveSplineDoneOpcode()

void WorldSession::HandleMoveSplineDoneOpcode ( WorldPacket recvPacket)
200{
201 ObjectGuid guid; // used only for proper packet read
202 recvData >> guid.ReadAsPacked();
203
204 MovementInfo movementInfo; // used only for proper packet read
205 movementInfo.guid = guid;
206 ReadMovementInfo(recvData, &movementInfo);
207
208 recvData.read_skip<uint32>(); // spline id
209
210 // in taxi flight packet received in 2 case:
211 // 1) end taxi path in far (multi-node) flight
212 // 2) switch from one map to other in case multim-map taxi path
213 // we need process only (1)
214
216 if (curDest)
217 {
218 TaxiNodesEntry const* curDestNode = sTaxiNodesStore.LookupEntry(curDest);
219
220 // far teleport case
221 if (curDestNode && curDestNode->map_id != GetPlayer()->GetMapId() && GetPlayer()->GetMotionMaster()->GetCurrentMovementGeneratorType() == FLIGHT_MOTION_TYPE)
222 {
223 if (FlightPathMovementGenerator* flight = dynamic_cast<FlightPathMovementGenerator*>(GetPlayer()->GetMotionMaster()->top()))
224 {
225 // short preparations to continue flight
226 flight->SetCurrentNodeAfterTeleport();
227 TaxiPathNodeEntry const* node = flight->GetPath()[flight->GetCurrentNode()];
228 flight->SkipCurrentNode();
229
230 GetPlayer()->TeleportTo(curDestNode->map_id, node->x, node->y, node->z, GetPlayer()->GetOrientation(), TELE_TO_NOT_LEAVE_TAXI);
231 }
232 }
233
234 return;
235 }
236
237 // at this point only 1 node is expected (final destination)
238 if (GetPlayer()->m_taxi.GetPath().size() != 1)
239 {
240 return;
241 }
242
244 GetPlayer()->SetFallInformation(GameTime::GetGameTime().count(), GetPlayer()->GetPositionZ());
245 if (GetPlayer()->pvpInfo.IsHostile)
246 {
247 GetPlayer()->CastSpell(GetPlayer(), 2479, true);
248 }
249}
@ FLIGHT_MOTION_TYPE
Definition: MotionMaster.h:45
DBCStorage< TaxiNodesEntry > sTaxiNodesStore(TaxiNodesEntryfmt)
@ TELE_TO_NOT_LEAVE_TAXI
Definition: Player.h:828
void SetFallInformation(uint32 time, float z)
Definition: Player.h:2318
PlayerTaxi m_taxi
Definition: Player.h:1143
void CleanupAfterTaxiFlight()
Definition: Player.cpp:10427
uint32 GetTaxiDestination() const
Definition: PlayerTaxi.h:64
Definition: WaypointMovementGenerator.h:106
Definition: DBCStructure.h:1952
uint32 map_id
Definition: DBCStructure.h:1954

References Unit::CastSpell(), Player::CleanupAfterTaxiFlight(), FLIGHT_MOTION_TYPE, GameTime::GetGameTime(), GetPlayer(), PlayerTaxi::GetTaxiDestination(), MovementInfo::guid, Player::m_taxi, TaxiNodesEntry::map_id, ByteBuffer::read_skip(), ObjectGuid::ReadAsPacked(), ReadMovementInfo(), Player::SetFallInformation(), sTaxiNodesStore, TELE_TO_NOT_LEAVE_TAXI, Player::TeleportTo(), TaxiPathNodeEntry::x, TaxiPathNodeEntry::y, and TaxiPathNodeEntry::z.

Referenced by OpcodeTable::Initialize().

◆ HandleMoveTeleportAck()

void WorldSession::HandleMoveTeleportAck ( WorldPacket recvPacket)
267{
268 LOG_DEBUG("network", "MSG_MOVE_TELEPORT_ACK");
269
270 ObjectGuid guid;
271 recvData >> guid.ReadAsPacked();
272
273 uint32 flags, time;
274 recvData >> flags >> time; // unused
275 LOG_DEBUG("network.opcode", "Guid {}", guid.ToString());
276 LOG_DEBUG("network.opcode", "Flags {}, time {}", flags, time / IN_MILLISECONDS);
277
278 Player* plMover = _player->m_mover->ToPlayer();
279
280 if (!plMover || !plMover->IsBeingTeleportedNear())
281 return;
282
283 if (guid != plMover->GetGUID())
284 return;
285
286 plMover->SetSemaphoreTeleportNear(0);
287
288 uint32 old_zone = plMover->GetZoneId();
289
290 WorldLocation const& dest = plMover->GetTeleportDest();
291 Position oldPos(*plMover);
292
293 plMover->UpdatePosition(dest, true);
294
295 // xinef: teleport pets if they are not unsummoned
296 if (Pet* pet = plMover->GetPet())
297 {
298 if (!pet->IsWithinDist3d(plMover, plMover->GetMap()->GetVisibilityRange() - 5.0f))
299 pet->NearTeleportTo(plMover->GetPositionX(), plMover->GetPositionY(), plMover->GetPositionZ(), pet->GetOrientation());
300 }
301
302 if (oldPos.GetExactDist2d(plMover) > 100.0f)
303 {
304 uint32 newzone, newarea;
305 plMover->GetZoneAndAreaId(newzone, newarea);
306 plMover->UpdateZone(newzone, newarea);
307
308 // new zone
309 if (old_zone != newzone)
310 {
311 // honorless target
312 if (plMover->pvpInfo.IsHostile)
313 plMover->CastSpell(plMover, 2479, true);
314
315 // in friendly area
316 else if (plMover->IsPvP() && !plMover->HasPlayerFlag(PLAYER_FLAGS_IN_PVP))
317 plMover->UpdatePvP(false, false);
318 }
319 }
320
321 // resummon pet
323
324 //lets process all delayed operations on successful teleport
326
328
329 // pussywizard: client forgets about losing control, resend it
330 if (plMover->HasUnitState(UNIT_STATE_FLEEING | UNIT_STATE_CONFUSED) || plMover->IsCharmed()) // only in such cases SetClientControl(self, false) is sent
331 plMover->SetClientControl(plMover, false, true);
332}
constexpr auto IN_MILLISECONDS
Definition: Common.h:53
@ UNIT_STATE_CONFUSED
Definition: UnitDefines.h:160
@ UNIT_STATE_FLEEING
Definition: UnitDefines.h:156
@ PLAYER_FLAGS_IN_PVP
Definition: Player.h:483
void GetZoneAndAreaId(uint32 &zoneid, uint32 &areaid) const
Definition: Object.cpp:3162
Definition: Position.h:28
bool IsHostile
Definition: Player.h:360
WorldLocation & GetTeleportDest()
Definition: Player.h:2071
void UpdatePvP(bool state, bool _override=false)
Definition: PlayerUpdates.cpp:1480
void UpdateZone(uint32 newZone, uint32 newArea)
Definition: PlayerUpdates.cpp:1207
void ProcessDelayedOperations()
Definition: Player.cpp:1614
bool UpdatePosition(float x, float y, float z, float orientation, bool teleport=false) override
Definition: PlayerUpdates.cpp:1111
void SetSemaphoreTeleportNear(time_t tm)
Definition: Player.h:2075
PvPInfo pvpInfo
Definition: Player.h:1829
bool IsBeingTeleportedNear() const
Definition: Player.h:2073
void SetClientControl(Unit *target, bool allowMove, bool packetOnly=false)
Definition: Player.cpp:12857
void ResummonPetTemporaryUnSummonedIfAny()
Definition: Player.cpp:14235
bool IsCharmed() const
Definition: Unit.h:1278
MotionMaster * GetMotionMaster()
Definition: Unit.h:1615
float GetVisibilityRange() const
Definition: Map.h:351
void ReinitializeMovement()
Definition: MotionMaster.cpp:904

References _player, Unit::CastSpell(), Position::GetExactDist2d(), Object::GetGUID(), WorldObject::GetMap(), Unit::GetMotionMaster(), Player::GetPet(), GetPlayer(), Position::GetPositionX(), Position::GetPositionY(), Position::GetPositionZ(), Player::GetTeleportDest(), Map::GetVisibilityRange(), WorldObject::GetZoneAndAreaId(), WorldObject::GetZoneId(), Player::HasPlayerFlag(), Unit::HasUnitState(), IN_MILLISECONDS, Player::IsBeingTeleportedNear(), Unit::IsCharmed(), PvPInfo::IsHostile, Player::IsPvP(), LOG_DEBUG, Player::m_mover, PLAYER_FLAGS_IN_PVP, Player::ProcessDelayedOperations(), Player::pvpInfo, ObjectGuid::ReadAsPacked(), MotionMaster::ReinitializeMovement(), Player::ResummonPetTemporaryUnSummonedIfAny(), Player::SetClientControl(), Player::SetSemaphoreTeleportNear(), Object::ToPlayer(), ObjectGuid::ToString(), UNIT_STATE_CONFUSED, UNIT_STATE_FLEEING, Player::UpdatePosition(), Player::UpdatePvP(), and Player::UpdateZone().

Referenced by HandleTeleportTimeout(), and OpcodeTable::Initialize().

◆ HandleMoveTimeSkippedOpcode()

void WorldSession::HandleMoveTimeSkippedOpcode ( WorldPacket recvData)
853{
854 LOG_DEBUG("network", "WORLD: Recvd CMSG_MOVE_TIME_SKIPPED");
855
856 ObjectGuid guid;
857 uint32 timeSkipped;
858 recvData >> guid.ReadAsPacked();
859 recvData >> timeSkipped;
860
861 Unit* mover = GetPlayer()->m_mover;
862
863 if (!mover)
864 {
865 LOG_ERROR("network.opcode", "WorldSession::HandleMoveTimeSkippedOpcode wrong mover state from the unit moved by the player [{}]", GetPlayer()->GetGUID().ToString());
866 return;
867 }
868
869 // prevent tampered movement data
870 if (guid != mover->GetGUID())
871 {
872 LOG_ERROR("network.opcode", "WorldSession::HandleMoveTimeSkippedOpcode wrong guid from the unit moved by the player [{}]", GetPlayer()->GetGUID().ToString());
873 return;
874 }
875
876 mover->m_movementInfo.time += timeSkipped;
877
878 WorldPacket data(MSG_MOVE_TIME_SKIPPED, recvData.size());
879 data << guid.WriteAsPacked();
880 data << timeSkipped;
881 GetPlayer()->SendMessageToSet(&data, false);
882}
@ MSG_MOVE_TIME_SKIPPED
Definition: Opcodes.h:823

References Object::GetGUID(), GetPlayer(), LOG_DEBUG, LOG_ERROR, WorldObject::m_movementInfo, Player::m_mover, MSG_MOVE_TIME_SKIPPED, ObjectGuid::ReadAsPacked(), Player::SendMessageToSet(), ByteBuffer::size(), MovementInfo::time, and ObjectGuid::WriteAsPacked().

Referenced by OpcodeTable::Initialize().

◆ HandleMoveUnRootAck()

void WorldSession::HandleMoveUnRootAck ( WorldPacket recvPacket)
995{
996 ObjectGuid guid;
997 recvData >> guid.ReadAsPacked();
998
999 Unit* mover = _player->m_mover;
1000 if (!mover || guid != mover->GetGUID())
1001 {
1002 recvData.rfinish(); // prevent warnings spam
1003 return;
1004 }
1005
1006 uint32 movementCounter;
1007 recvData >> movementCounter;
1008
1009 MovementInfo movementInfo;
1010 movementInfo.guid = guid;
1011 ReadMovementInfo(recvData, &movementInfo);
1012
1013 /* process position-change */
1014 int64 movementTime = (int64) movementInfo.time + _timeSyncClockDelta;
1015 if (_timeSyncClockDelta == 0 || movementTime < 0 || movementTime > 0xFFFFFFFF)
1016 {
1017 LOG_INFO("misc", "The computed movement time using clockDelta is erronous. Using fallback instead");
1018 movementInfo.time = getMSTime();
1019 }
1020 else
1021 {
1022 movementInfo.time = (uint32)movementTime;
1023 }
1024
1025 if (G3D::fuzzyEq(movementInfo.fallTime, 0.f))
1026 {
1028 }
1029
1030 movementInfo.guid = mover->GetGUID();
1031 mover->m_movementInfo = movementInfo;
1032 mover->UpdatePosition(movementInfo.pos);
1033
1034 WorldPacket data(MSG_MOVE_UNROOT, 64);
1035 WriteMovementInfo(&data, &movementInfo);
1036 mover->SendMessageToSet(&data, _player);
1037}
@ MSG_MOVE_UNROOT
Definition: Opcodes.h:267
uint32 fallTime
Definition: Object.h:307

References _player, _timeSyncClockDelta, MovementInfo::fallTime, Object::GetGUID(), getMSTime(), MovementInfo::guid, LOG_INFO, WorldObject::m_movementInfo, Player::m_mover, MOVEMENTFLAG_FALLING, MSG_MOVE_UNROOT, MovementInfo::pos, ObjectGuid::ReadAsPacked(), ReadMovementInfo(), MovementInfo::RemoveMovementFlag(), ByteBuffer::rfinish(), WorldObject::SendMessageToSet(), MovementInfo::time, Unit::UpdatePosition(), and WriteMovementInfo().

Referenced by OpcodeTable::Initialize().

◆ HandleMoveWaterWalkAck()

void WorldSession::HandleMoveWaterWalkAck ( WorldPacket recvPacket)
813{
814 LOG_DEBUG("network", "CMSG_MOVE_WATER_WALK_ACK");
815
816 ObjectGuid guid;
817 recvData >> guid.ReadAsPacked();
818
819 recvData.read_skip<uint32>(); // unk
820
821 MovementInfo movementInfo;
822 movementInfo.guid = guid;
823 ReadMovementInfo(recvData, &movementInfo);
824
825 recvData.read_skip<uint32>(); // unk2
826}

References MovementInfo::guid, LOG_DEBUG, ByteBuffer::read_skip(), ObjectGuid::ReadAsPacked(), and ReadMovementInfo().

Referenced by OpcodeTable::Initialize().

◆ HandleMoveWorldportAck()

void WorldSession::HandleMoveWorldportAck ( )
51{
52 // ignore unexpected far teleports
53 if (!GetPlayer()->IsBeingTeleportedFar())
54 return;
55
57
58 // get the teleport destination
59 WorldLocation const& loc = GetPlayer()->GetTeleportDest();
60
61 // possible errors in the coordinate validity check
63 {
64 KickPlayer("!MapMgr::IsValidMapCoord(loc)");
65 return;
66 }
67
68 // get the destination map entry, not the current one, this will fix homebind and reset greeting
69 MapEntry const* mEntry = sMapStore.LookupEntry(loc.GetMapId());
70 InstanceTemplate const* mInstance = sObjectMgr->GetInstanceTemplate(loc.GetMapId());
71
72 Map* oldMap = GetPlayer()->GetMap();
73 if (GetPlayer()->IsInWorld())
74 {
75 LOG_ERROR("network.opcode", "Player (Name {}) is still in world when teleported from map {} to new map {}", GetPlayer()->GetName(), oldMap->GetId(), loc.GetMapId());
76 oldMap->RemovePlayerFromMap(GetPlayer(), false);
77 }
78
79 // reset instance validity, except if going to an instance inside an instance
80 if (!GetPlayer()->m_InstanceValid && !mInstance)
81 {
82 GetPlayer()->m_InstanceValid = true;
83 // pussywizard: m_InstanceValid can be false only by leaving a group in an instance => so remove temp binds that could not be removed because player was still on the map!
84 if (!sInstanceSaveMgr->PlayerIsPermBoundToInstance(GetPlayer()->GetGUID(), oldMap->GetId(), oldMap->GetDifficulty()))
85 sInstanceSaveMgr->PlayerUnbindInstance(GetPlayer()->GetGUID(), oldMap->GetId(), oldMap->GetDifficulty(), true);
86 }
87
88 // relocate the player to the teleport destination
89 Map* newMap = sMapMgr->CreateMap(loc.GetMapId(), GetPlayer());
90 // the CanEnter checks are done in TeleporTo but conditions may change
91 // while the player is in transit, for example the map may get full
92 if (!newMap || newMap->CannotEnter(GetPlayer(), false))
93 {
94 LOG_ERROR("network.opcode", "Map {} could not be created for player {}, porting player to homebind", loc.GetMapId(), GetPlayer()->GetGUID().ToString());
95 GetPlayer()->TeleportTo(GetPlayer()->m_homebindMapId, GetPlayer()->m_homebindX, GetPlayer()->m_homebindY, GetPlayer()->m_homebindZ, GetPlayer()->GetOrientation());
96 return;
97 }
98
99 float z = loc.GetPositionZ() + GetPlayer()->GetHoverHeight();
100 GetPlayer()->Relocate(loc.GetPositionX(), loc.GetPositionY(), z, loc.GetOrientation());
101
102 GetPlayer()->ResetMap();
103 GetPlayer()->SetMap(newMap);
104
106
108 if (!GetPlayer()->GetMap()->AddPlayerToMap(GetPlayer()))
109 {
110 LOG_ERROR("network.opcode", "WORLD: failed to teleport player {} ({}) to map {} because of unknown reason!",
111 GetPlayer()->GetName(), GetPlayer()->GetGUID().ToString(), loc.GetMapId());
112 GetPlayer()->ResetMap();
113 GetPlayer()->SetMap(oldMap);
114 GetPlayer()->TeleportTo(GetPlayer()->m_homebindMapId, GetPlayer()->m_homebindX, GetPlayer()->m_homebindY, GetPlayer()->m_homebindZ, GetPlayer()->GetOrientation());
115 return;
116 }
117
118 oldMap->AfterPlayerUnlinkFromMap();
119
120 // pussywizard: transport teleport couldn't teleport us to the same map (some other teleport pending, reqs not met, etc.), but we still have transport set until player moves! clear it if map differs (crashfix)
121 if (Transport* t = _player->GetTransport())
122 if (!t->IsInMap(_player))
123 {
124 t->RemovePassenger(_player);
125 _player->m_transport = nullptr;
128 }
129
131 _player->getHostileRefMgr().deleteReferences(true); // pussywizard: multithreading crashfix
132
133 CellCoord pair(Acore::ComputeCellCoord(GetPlayer()->GetPositionX(), GetPlayer()->GetPositionY()));
134 Cell cell(pair);
135 if (!GridCoord(cell.GridX(), cell.GridY()).IsCoordValid())
136 {
137 KickPlayer("!GridCoord(cell.GridX(), cell.GridY()).IsCoordValid()");
138 return;
139 }
140 newMap->LoadGrid(GetPlayer()->GetPositionX(), GetPlayer()->GetPositionY());
141
142 // pussywizard: player supposed to enter bg map
143 if (_player->InBattleground())
144 {
145 // but landed on another map, cleanup data
146 if (!mEntry->IsBattlegroundOrArena())
148 // everything ok
149 else if (Battleground* bg = _player->GetBattleground())
150 {
151 if (_player->IsInvitedForBattlegroundInstance()) // GMs are not invited, so they are not added to participants
152 bg->AddPlayer(_player);
153 }
154 }
155
156 // pussywizard: arena spectator stuff
157 {
158 if (newMap->IsBattleArena() && ((BattlegroundMap*)newMap)->GetBG() && _player->HasPendingSpectatorForBG(((BattlegroundMap*)newMap)->GetInstanceId()))
159 {
161 _player->SetIsSpectator(true);
163 ((BattlegroundMap*)newMap)->GetBG()->AddSpectator(_player);
165 }
166 else
167 _player->SetIsSpectator(false);
168
170
171 if (uint32 inviteInstanceId = _player->GetPendingSpectatorInviteInstanceId())
172 {
173 if (Battleground* tbg = sBattlegroundMgr->GetBattleground(inviteInstanceId, BATTLEGROUND_TYPE_NONE))
174 tbg->RemoveToBeTeleported(_player->GetGUID());
176 }
177 }
178
179 // xinef: do this again, player can be teleported inside bg->AddPlayer(_player)!!!!
180 CellCoord pair2(Acore::ComputeCellCoord(GetPlayer()->GetPositionX(), GetPlayer()->GetPositionY()));
181 Cell cell2(pair2);
182 if (!GridCoord(cell2.GridX(), cell2.GridY()).IsCoordValid())
183 {
184 KickPlayer("!GridCoord(cell2.GridX(), cell2.GridY()).IsCoordValid()");
185 return;
186 }
187 newMap->LoadGrid(GetPlayer()->GetPositionX(), GetPlayer()->GetPositionY());
188
190
191 // flight fast teleport case
192 if (GetPlayer()->IsInFlight())
193 {
194 if (!GetPlayer()->InBattleground())
195 {
196 // short preparations to continue flight
197 MovementGenerator* movementGenerator = GetPlayer()->GetMotionMaster()->top();
198 movementGenerator->Initialize(GetPlayer());
199 return;
200 }
201
202 // battleground state prepare, stop flight
205 }
206
207 // resurrect character at enter into instance where his corpse exist after add to map
208 Corpse* corpse = GetPlayer()->GetMap()->GetCorpseByPlayer(GetPlayer()->GetGUID());
209 if (corpse && corpse->GetType() != CORPSE_BONES)
210 {
211 if (mEntry->IsDungeon())
212 {
213 GetPlayer()->ResurrectPlayer(0.5f);
215 }
216 }
217
218 if (!corpse && mEntry->IsDungeon())
219 {
220 // resurrect character upon entering instance when the corpse is not available anymore
221 if (GetPlayer()->GetCorpseLocation().GetMapId() == mEntry->MapID)
222 {
223 GetPlayer()->ResurrectPlayer(0.5f);
225 }
226 }
227
228 bool allowMount = !mEntry->IsDungeon() || mEntry->IsBattlegroundOrArena();
229 if (mInstance)
230 {
231 Difficulty diff = GetPlayer()->GetDifficulty(mEntry->IsRaid());
232 if (MapDifficulty const* mapDiff = GetMapDifficultyData(mEntry->MapID, diff))
233 if (mapDiff->resetTime)
234 if (time_t timeReset = sInstanceSaveMgr->GetResetTimeFor(mEntry->MapID, diff))
235 {
236 uint32 timeleft = uint32(timeReset - GameTime::GetGameTime().count());
237 GetPlayer()->SendInstanceResetWarning(mEntry->MapID, diff, timeleft, true);
238 }
239 allowMount = mInstance->AllowMount;
240 }
241
242 // mount allow check
243 if (!allowMount)
245
246 // update zone immediately, otherwise leave channel will cause crash in mtmap
247 uint32 newzone, newarea;
248 GetPlayer()->GetZoneAndAreaId(newzone, newarea);
249 GetPlayer()->UpdateZone(newzone, newarea);
250
251 // honorless target
252 if (GetPlayer()->pvpInfo.IsHostile)
253 GetPlayer()->CastSpell(GetPlayer(), 2479, true);
254
255 // in friendly area
256 else if (GetPlayer()->IsPvP() && !GetPlayer()->HasPlayerFlag(PLAYER_FLAGS_IN_PVP))
257 GetPlayer()->UpdatePvP(false, false);
258
259 // resummon pet
261
262 //lets process all delayed operations on successful teleport
264}
CoordPair< MAX_NUMBER_OF_GRIDS > GridCoord
Definition: GridDefines.h:169
MapDifficulty const * GetMapDifficultyData(uint32 mapId, Difficulty difficulty)
Definition: DBCStores.cpp:761
#define SPECTATOR_ADDON_PREFIX
Definition: ArenaSpectator.h:35
@ CORPSE_BONES
Definition: Corpse.h:28
@ BATTLEGROUND_TYPE_NONE
Definition: SharedDefines.h:3480
CellCoord ComputeCellCoord(float x, float y)
Definition: GridDefines.h:191
AC_GAME_API void HandleResetCommand(Player *player)
Definition: ArenaSpectator.cpp:227
void SendCommand(T *o, Format &&fmt, Args &&... args)
Definition: ArenaSpectator.h:47
bool IsEmpty() const
Definition: LinkedList.h:97
void deleteReferences(bool removeFromMap=false)
Definition: HostileRefMgr.cpp:125
CorpseType GetType() const
Definition: Corpse.h:72
void UpdatePositionData()
Definition: Object.cpp:1154
bool HasPendingSpectatorForBG(uint32 bgInstanceId) const
Definition: Player.h:2562
void SendInitialPacketsAfterAddToMap()
Definition: Player.cpp:11634
bool m_InstanceValid
Definition: Player.h:2418
void SendInstanceResetWarning(uint32 mapid, Difficulty difficulty, uint32 time, bool onEnterMap)
Definition: Player.cpp:11735
bool IsInvitedForBattlegroundInstance() const
Definition: Player.h:2239
Difficulty GetDifficulty(bool isRaid) const
Definition: Player.h:1902
void SendInitialPacketsBeforeAddToMap()
Definition: Player.cpp:11577
void ResetMap() override
Definition: Player.cpp:14665
void RemoveCorpse()
Definition: Player.cpp:4658
void ClearReceivedSpectatorResetFor()
Definition: Player.h:2566
void SetPendingSpectatorInviteInstanceId(uint32 bgInstanceId)
Definition: Player.h:2563
void SetIsSpectator(bool on)
Definition: Player.cpp:15360
void SetSemaphoreTeleportFar(time_t tm)
Definition: Player.h:2076
void SetMap(Map *map) override
Definition: Player.cpp:14677
void SetPendingSpectatorForBG(uint32 bgInstanceId)
Definition: Player.h:2561
uint32 GetPendingSpectatorInviteInstanceId() const
Definition: Player.h:2564
HostileRefMgr & getHostileRefMgr()
Definition: Unit.h:843
float GetHoverHeight() const
Definition: Unit.h:1717
Definition: Cell.h:45
Definition: Map.h:274
bool AllowMount
Definition: Map.h:277
virtual void RemovePlayerFromMap(Player *, bool)
Definition: Map.cpp:911
void LoadGrid(float x, float y)
Definition: Map.cpp:492
virtual void AfterPlayerUnlinkFromMap()
Definition: Map.cpp:934
virtual EnterState CannotEnter(Player *, bool)
Definition: Map.h:438
uint32 GetId() const
Definition: Map.h:379
Corpse * GetCorpseByPlayer(ObjectGuid const &ownerGuid) const
Definition: Map.h:534
Difficulty GetDifficulty() const
Definition: Map.h:443
Definition: Map.h:853
static bool IsValidMapCoord(uint32 mapid, Position const &pos)
Definition: MapMgr.h:91
_Ty top() const
Definition: MotionMaster.h:148
void MovementExpired(bool reset=true)
Definition: MotionMaster.h:178
Definition: MovementGenerator.h:28
virtual void Initialize(Unit *)=0
uint32 MapID
Definition: DBCStructure.h:1325
bool IsBattlegroundOrArena() const
Definition: DBCStructure.h:1356
bool IsDungeon() const
Definition: DBCStructure.h:1350
Definition: DBCStructure.h:2221

References _player, Map::AfterPlayerUnlinkFromMap(), InstanceTemplate::AllowMount, BATTLEGROUND_TYPE_NONE, Map::CannotEnter(), Unit::CastSpell(), Player::CleanupAfterTaxiFlight(), Player::ClearReceivedSpectatorResetFor(), Acore::ComputeCellCoord(), CORPSE_BONES, HostileRefMgr::deleteReferences(), Player::GetBattleground(), Map::GetCorpseByPlayer(), Map::GetDifficulty(), Player::GetDifficulty(), GameTime::GetGameTime(), Object::GetGUID(), Unit::getHostileRefMgr(), Unit::GetHoverHeight(), Map::GetId(), WorldObject::GetMap(), GetMapDifficultyData(), WorldLocation::GetMapId(), Unit::GetMotionMaster(), Position::GetOrientation(), Player::GetPendingSpectatorInviteInstanceId(), GetPlayer(), Position::GetPositionX(), Position::GetPositionY(), Position::GetPositionZ(), Player::GetTeleportDest(), WorldObject::GetTransport(), Corpse::GetType(), WorldObject::GetZoneAndAreaId(), Cell::GridX(), Cell::GridY(), ArenaSpectator::HandleResetCommand(), Player::HasPendingSpectatorForBG(), Player::InBattleground(), MovementGenerator::Initialize(), Map::IsBattleArena(), MapEntry::IsBattlegroundOrArena(), MapEntry::IsDungeon(), LinkedListHead::IsEmpty(), Player::IsInvitedForBattlegroundInstance(), MapEntry::IsRaid(), MapMgr::IsValidMapCoord(), KickPlayer(), Map::LoadGrid(), LOG_ERROR, Player::m_InstanceValid, WorldObject::m_movementInfo, WorldObject::m_transport, MapEntry::MapID, MotionMaster::MovementExpired(), MOVEMENTFLAG_ONTRANSPORT, PLAYER_FLAGS_IN_PVP, PLAYER_MAX_BATTLEGROUND_QUEUES, Player::ProcessDelayedOperations(), Position::Relocate(), Unit::RemoveAurasByType(), Player::RemoveCorpse(), MovementInfo::RemoveMovementFlag(), Map::RemovePlayerFromMap(), MovementInfo::TransportInfo::Reset(), Player::ResetMap(), Player::ResummonPetTemporaryUnSummonedIfAny(), Player::ResurrectPlayer(), sBattlegroundMgr, ArenaSpectator::SendCommand(), Player::SendInitialPacketsAfterAddToMap(), Player::SendInitialPacketsBeforeAddToMap(), Player::SendInstanceResetWarning(), Player::SetBattlegroundId(), Player::SetIsSpectator(), Player::SetMap(), Player::SetPendingSpectatorForBG(), Player::SetPendingSpectatorInviteInstanceId(), Player::SetSemaphoreTeleportFar(), sInstanceSaveMgr, sMapMgr, sMapStore, sObjectMgr, Player::SpawnCorpseBones(), SPECTATOR_ADDON_PREFIX, SPELL_AURA_MOUNTED, TEAM_NEUTRAL, Player::TeleportTo(), MotionMaster::top(), MovementInfo::transport, WorldObject::UpdatePositionData(), Player::UpdatePvP(), and Player::UpdateZone().

Referenced by HandleMoveWorldportAckOpcode(), HandleTeleportTimeout(), and LogoutPlayer().

◆ HandleMoveWorldportAckOpcode()

void WorldSession::HandleMoveWorldportAckOpcode ( WorldPacket recvPacket)
45{
46 LOG_DEBUG("network", "WORLD: got MSG_MOVE_WORLDPORT_ACK.");
48}
void HandleMoveWorldportAck()
Definition: MovementHandler.cpp:50

References HandleMoveWorldportAck(), and LOG_DEBUG.

Referenced by OpcodeTable::Initialize().

◆ HandleNameQueryOpcode()

void WorldSession::HandleNameQueryOpcode ( WorldPacket recvPacket)
68{
69 ObjectGuid guid;
70 recvData >> guid;
71
72 // This is disable by default to prevent lots of console spam
73 // LOG_INFO("network.opcode", "HandleNameQueryOpcode {}", guid);
74
76}
void SendNameQueryOpcode(ObjectGuid guid)
Definition: QueryHandler.cpp:31

References SendNameQueryOpcode().

Referenced by OpcodeTable::Initialize().

◆ HandleNextCinematicCamera()

void WorldSession::HandleNextCinematicCamera ( WorldPacket recvPacket)
984{
985 // Sent by client when cinematic actually begun. So we begin the server side process
987}
void BeginCinematic()
Definition: CinematicMgr.cpp:41

References CinematicMgr::BeginCinematic(), Player::GetCinematicMgr(), and GetPlayer().

Referenced by OpcodeTable::Initialize().

◆ HandleNpcTextQueryOpcode()

void WorldSession::HandleNpcTextQueryOpcode ( WorldPacket recvPacket)
281{
282 uint32 textID;
283 ObjectGuid guid;
284
285 recvData >> textID;
286 LOG_DEBUG("network", "WORLD: CMSG_NPC_TEXT_QUERY TextId: {}", textID);
287
288 recvData >> guid;
289
290 GossipText const* gossip = sObjectMgr->GetGossipText(textID);
291
292 WorldPacket data(SMSG_NPC_TEXT_UPDATE, 100); // guess size
293 data << textID;
294
295 if (!gossip)
296 {
297 for (uint8 i = 0; i < MAX_GOSSIP_TEXT_OPTIONS; ++i)
298 {
299 data << float(0);
300 data << "Greetings $N";
301 data << "Greetings $N";
302 data << uint32(0);
303 data << uint32(0);
304 data << uint32(0);
305 data << uint32(0);
306 data << uint32(0);
307 data << uint32(0);
308 data << uint32(0);
309 }
310 }
311 else
312 {
313 std::string text0[MAX_GOSSIP_TEXT_OPTIONS], text1[MAX_GOSSIP_TEXT_OPTIONS];
315
316 for (uint8 i = 0; i < MAX_GOSSIP_TEXT_OPTIONS; ++i)
317 {
318 BroadcastText const* bct = sObjectMgr->GetBroadcastText(gossip->Options[i].BroadcastTextID);
319 if (bct)
320 {
321 text0[i] = bct->GetText(locale, GENDER_MALE, true);
322 text1[i] = bct->GetText(locale, GENDER_FEMALE, true);
323 }
324 else
325 {
326 text0[i] = gossip->Options[i].Text_0;
327 text1[i] = gossip->Options[i].Text_1;
328 }
329
330 if (locale != DEFAULT_LOCALE && !bct)
331 {
332 if (NpcTextLocale const* npcTextLocale = sObjectMgr->GetNpcTextLocale(textID))
333 {
334 ObjectMgr::GetLocaleString(npcTextLocale->Text_0[i], locale, text0[i]);
335 ObjectMgr::GetLocaleString(npcTextLocale->Text_1[i], locale, text1[i]);
336 }
337 }
338
339 data << gossip->Options[i].Probability;
340
341 if (text0[i].empty())
342 data << text1[i];
343 else
344 data << text0[i];
345
346 if (text1[i].empty())
347 data << text0[i];
348 else
349 data << text1[i];
350
351 data << gossip->Options[i].Language;
352
353 for (uint8 j = 0; j < MAX_GOSSIP_TEXT_EMOTES; ++j)
354 {
355 data << gossip->Options[i].Emotes[j]._Delay;
356 data << gossip->Options[i].Emotes[j]._Emote;
357 }
358 }
359 }
360
361 SendPacket(&data);
362
363 LOG_DEBUG("network", "WORLD: Sent SMSG_NPC_TEXT_UPDATE");
364}
#define DEFAULT_LOCALE
Definition: Common.h:79
#define MAX_GOSSIP_TEXT_OPTIONS
Definition: NPCHandler.h:42
#define MAX_GOSSIP_TEXT_EMOTES
Definition: NPCHandler.h:30
@ GENDER_MALE
Definition: SharedDefines.h:61
@ GENDER_FEMALE
Definition: SharedDefines.h:62
@ SMSG_NPC_TEXT_UPDATE
Definition: Opcodes.h:414
Definition: ObjectMgr.h:433
std::string const & GetText(LocaleConstant locale=DEFAULT_LOCALE, uint8 gender=GENDER_MALE, bool forceGender=false) const
Definition: ObjectMgr.h:455
uint32 _Emote
Definition: NPCHandler.h:26
uint32 _Delay
Definition: NPCHandler.h:27
std::string Text_0
Definition: NPCHandler.h:34
QEmote Emotes[MAX_GOSSIP_TEXT_EMOTES]
Definition: NPCHandler.h:39
uint32 Language
Definition: NPCHandler.h:37
float Probability
Definition: NPCHandler.h:38
uint32 BroadcastTextID
Definition: NPCHandler.h:36
std::string Text_1
Definition: NPCHandler.h:35
Definition: NPCHandler.h:45
GossipTextOption Options[MAX_GOSSIP_TEXT_OPTIONS]
Definition: NPCHandler.h:46
Definition: NPCHandler.h:55

References QEmote::_Delay, QEmote::_Emote, GossipTextOption::BroadcastTextID, DEFAULT_LOCALE, GossipTextOption::Emotes, GENDER_FEMALE, GENDER_MALE, ObjectMgr::GetLocaleString(), GetSessionDbLocaleIndex(), BroadcastText::GetText(), GossipTextOption::Language, LOG_DEBUG, MAX_GOSSIP_TEXT_EMOTES, MAX_GOSSIP_TEXT_OPTIONS, GossipText::Options, GossipTextOption::Probability, SendPacket(), SMSG_NPC_TEXT_UPDATE, sObjectMgr, GossipTextOption::Text_0, and GossipTextOption::Text_1.

Referenced by OpcodeTable::Initialize().

◆ HandleOfferPetitionOpcode()

void WorldSession::HandleOfferPetitionOpcode ( WorldPacket recvData)
551{
552 LOG_DEBUG("network", "Received opcode CMSG_OFFER_PETITION"); // ok
553
554 ObjectGuid petitionguid, plguid;
555 uint32 junk;
556 Player* player;
557 recvData >> junk; // this is not petition type!
558 recvData >> petitionguid; // petition guid
559 recvData >> plguid; // player guid
560
562 if (!player)
563 return;
564
565 Petition const* petition = sPetitionMgr->GetPetition(petitionguid);
566 if (!petition)
567 return;
568
569 if (petition->petitionType != GUILD_CHARTER_TYPE)
570 {
571 if (GetPlayer()->GetTeamId() != player->GetTeamId() && !sWorld->getBoolConfig(CONFIG_ALLOW_TWO_SIDE_INTERACTION_ARENA))
572 {
574 return;
575 }
576
577 if (player->GetLevel() < sWorld->getIntConfig(CONFIG_MAX_PLAYER_LEVEL))
578 {
579 // player is too low level to join an arena team
581 return;
582 }
583
585 if (slot >= MAX_ARENA_SLOT)
586 return;
587
588 if (player->GetArenaTeamId(slot))
589 {
590 // player is already in an arena team
592 return;
593 }
594
595 if (player->GetArenaTeamIdInvited())
596 {
598 return;
599 }
600 }
601 else
602 {
603 if (GetPlayer()->GetTeamId() != player->GetTeamId() && !sWorld->getBoolConfig(CONFIG_ALLOW_TWO_SIDE_INTERACTION_GUILD))
604 {
606 return;
607 }
608
609 if (player->GetGuildId())
610 {
612 return;
613 }
614
615 if (player->GetGuildIdInvited())
616 {
618 return;
619 }
620 }
621
622 Signatures const* signatures = sPetitionMgr->GetSignature(petitionguid);
623 uint8 signs = signatures ? signatures->signatureMap.size() : 0;
624
625 WorldPacket data(SMSG_PETITION_SHOW_SIGNATURES, (8 + 8 + 4 + signs + signs * 12));
626 data << petitionguid; // petition guid
627 data << _player->GetGUID(); // owner guid
628 data << uint32(petitionguid.GetCounter()); // guild guid
629 data << uint8(signs); // sign's count
630
631 if (signs)
632 for (SignatureMap::const_iterator itr = signatures->signatureMap.begin(); itr != signatures->signatureMap.end(); ++itr)
633 {
634 data << itr->first; // Player GUID
635 data << uint32(0); // there 0 ...
636 }
637
638 player->GetSession()->SendPacket(&data);
639}
@ GUILD_COMMAND_INVITE
Definition: Guild.h:103
@ GUILD_COMMAND_CREATE
Definition: Guild.h:102
@ ERR_ALREADY_IN_GUILD_S
Definition: Guild.h:125
@ ERR_GUILD_NOT_ALLIED
Definition: Guild.h:135
@ ERR_ALREADY_INVITED_TO_GUILD_S
Definition: Guild.h:127
#define sPetitionMgr
Definition: PetitionMgr.h:88
@ SMSG_PETITION_SHOW_SIGNATURES
Definition: Opcodes.h:477
@ GUILD_CHARTER_TYPE
Definition: WorldSession.h:222
static uint8 GetSlotByType(uint32 type)
Definition: ArenaTeam.cpp:618
uint32 GetGuildIdInvited()
Definition: Player.h:1885
Definition: PetitionMgr.h:40
uint8 petitionType
Definition: PetitionMgr.h:43
Definition: PetitionMgr.h:48
SignatureMap signatureMap
Definition: PetitionMgr.h:50

References _player, CONFIG_ALLOW_TWO_SIDE_INTERACTION_ARENA, CONFIG_ALLOW_TWO_SIDE_INTERACTION_GUILD, CONFIG_MAX_PLAYER_LEVEL, ERR_ALREADY_IN_ARENA_TEAM_S, ERR_ALREADY_IN_GUILD_S, ERR_ALREADY_INVITED_TO_ARENA_TEAM_S, ERR_ALREADY_INVITED_TO_GUILD_S, ERR_ARENA_TEAM_CREATE_S, ERR_ARENA_TEAM_INVITE_SS, ERR_ARENA_TEAM_NOT_ALLIED, ERR_ARENA_TEAM_TARGET_TOO_LOW_S, ERR_GUILD_NOT_ALLIED, ObjectAccessor::FindConnectedPlayer(), Player::GetArenaTeamId(), Player::GetArenaTeamIdInvited(), ObjectGuid::GetCounter(), Object::GetGUID(), Player::GetGuildId(), Player::GetGuildIdInvited(), Unit::GetLevel(), WorldObject::GetName(), GetPlayer(), Player::GetSession(), ArenaTeam::GetSlotByType(), Player::GetTeamId(), GetTeamId(), GUILD_CHARTER_TYPE, GUILD_COMMAND_CREATE, GUILD_COMMAND_INVITE, LOG_DEBUG, MAX_ARENA_SLOT, Petition::petitionType, SendArenaTeamCommandResult(), Guild::SendCommandResult(), SendPacket(), Signatures::signatureMap, SMSG_PETITION_SHOW_SIGNATURES, sPetitionMgr, and sWorld.

Referenced by OpcodeTable::Initialize().

◆ HandleOpenItemOpcode()

void WorldSession::HandleOpenItemOpcode ( WorldPacket recvPacket)
169{
170 LOG_DEBUG("network", "WORLD: CMSG_OPEN_ITEM packet, data length = {}", (uint32)recvPacket.size());
171
172 Player* pUser = _player;
173
174 // ignore for remote control state
175 if (pUser->m_mover != pUser)
176 return;
177
178 // xinef: additional check, client outputs message on its own
179 if (!pUser->IsAlive())
180 {
181 pUser->SendEquipError(EQUIP_ERR_YOU_ARE_DEAD, nullptr, nullptr);
182 return;
183 }
184
185 uint8 bagIndex, slot;
186
187 recvPacket >> bagIndex >> slot;
188
189 LOG_DEBUG("network.opcode", "bagIndex: {}, slot: {}", bagIndex, slot);
190
191 Item* item = pUser->GetItemByPos(bagIndex, slot);
192 if (!item)
193 {
194 pUser->SendEquipError(EQUIP_ERR_ITEM_NOT_FOUND, nullptr, nullptr);
195 return;
196 }
197
198 ItemTemplate const* proto = item->GetTemplate();
199 if (!proto)
200 {
201 pUser->SendEquipError(EQUIP_ERR_ITEM_NOT_FOUND, item, nullptr);
202 return;
203 }
204
205 // Verify that the bag is an actual bag or wrapped item that can be used "normally"
206 if (!proto->HasFlag(ITEM_FLAG_HAS_LOOT) && !item->IsWrapped())
207 {
208 pUser->SendEquipError(EQUIP_ERR_CANT_DO_RIGHT_NOW, item, nullptr);
209 LOG_ERROR("network.opcode", "Possible hacking attempt: Player {} [{}] tried to open item [{}, entry: {}] which is not openable!",
210 pUser->GetName(), pUser->GetGUID().ToString(), item->GetGUID().ToString(), proto->ItemId);
211 return;
212 }
213
214 // locked item
215 uint32 lockId = proto->LockID;
216 if (lockId)
217 {
218 LockEntry const* lockInfo = sLockStore.LookupEntry(lockId);
219
220 if (!lockInfo)
221 {
222 pUser->SendEquipError(EQUIP_ERR_ITEM_LOCKED, item, nullptr);
223 LOG_ERROR("network.opcode", "WORLD::OpenItem: item [{}] has an unknown lockId: {}!", item->GetGUID().ToString(), lockId);
224 return;
225 }
226
227 // was not unlocked yet
228 if (item->IsLocked())
229 {
230 pUser->SendEquipError(EQUIP_ERR_ITEM_LOCKED, item, nullptr);
231 return;
232 }
233 }
234
235 if (sScriptMgr->OnBeforeOpenItem(pUser, item))
236 {
237 if (item->IsWrapped())// wrapped?
238 {
240 stmt->SetData(0, item->GetGUID().GetCounter());
242 .WithPreparedCallback(std::bind(&WorldSession::HandleOpenWrappedItemCallback, this, bagIndex, slot, item->GetGUID().GetCounter(), std::placeholders::_1)));
243 }
244 else
245 {
246 pUser->SendLoot(item->GetGUID(), LOOT_CORPSE);
247 }
248 }
249}
DBCStorage< LockEntry > sLockStore(LockEntryfmt)
@ EQUIP_ERR_ITEM_LOCKED
Definition: Item.h:83
@ EQUIP_ERR_YOU_ARE_DEAD
Definition: Item.h:85
@ EQUIP_ERR_CANT_DO_RIGHT_NOW
Definition: Item.h:86
@ CHAR_SEL_CHARACTER_GIFT_BY_ITEM
Definition: CharacterDatabase.h:131
bool IsWrapped() const
Definition: Item.h:263
bool IsLocked() const
Definition: Item.h:253
void HandleOpenWrappedItemCallback(uint8 bagIndex, uint8 slot, ObjectGuid::LowType itemLowGUID, PreparedQueryResult result)
Definition: SpellHandler.cpp:251
Definition: DBCStructure.h:1307

References _player, _queryProcessor, AsyncCallbackProcessor< T >::AddCallback(), CHAR_SEL_CHARACTER_GIFT_BY_ITEM, CharacterDatabase, EQUIP_ERR_CANT_DO_RIGHT_NOW, EQUIP_ERR_ITEM_LOCKED, EQUIP_ERR_ITEM_NOT_FOUND, EQUIP_ERR_YOU_ARE_DEAD, ObjectGuid::GetCounter(), Object::GetGUID(), Player::GetItemByPos(), WorldObject::GetName(), Item::GetTemplate(), HandleOpenWrappedItemCallback(), ItemTemplate::HasFlag(), Unit::IsAlive(), Item::IsLocked(), Item::IsWrapped(), ITEM_FLAG_HAS_LOOT, ItemTemplate::ItemId, ItemTemplate::LockID, LOG_DEBUG, LOG_ERROR, LOOT_CORPSE, Player::m_mover, Player::SendEquipError(), Player::SendLoot(), PreparedStatementBase::SetData(), ByteBuffer::size(), sLockStore, sScriptMgr, and ObjectGuid::ToString().

Referenced by OpcodeTable::Initialize().

◆ HandleOpenWrappedItemCallback()

void WorldSession::HandleOpenWrappedItemCallback ( uint8  bagIndex,
uint8  slot,
ObjectGuid::LowType  itemLowGUID,
PreparedQueryResult  result 
)
252{
253 if (!GetPlayer())
254 return;
255
256 Item* item = GetPlayer()->GetItemByPos(bagIndex, slot);
257 if (!item)
258 return;
259
260 if (item->GetGUID().GetCounter() != itemLowGUID || !item->IsWrapped()) // during getting result, gift was swapped with another item
261 return;
262
263 if (!result)
264 {
265 LOG_ERROR("network", "Wrapped item {} don't have record in character_gifts table and will deleted", item->GetGUID().ToString());
266 GetPlayer()->DestroyItem(item->GetBagSlot(), item->GetSlot(), true);
267 return;
268 }
269
270 CharacterDatabaseTransaction trans = CharacterDatabase.BeginTransaction();
271
272 Field* fields = result->Fetch();
273 uint32 entry = fields[0].Get<uint32>();
274 uint32 flags = fields[1].Get<uint32>();
275
277 item->SetEntry(entry);
278 item->SetUInt32Value(ITEM_FIELD_FLAGS, flags);
280
283
285 stmt->SetData(0, item->GetGUID().GetCounter());
286 trans->Append(stmt);
287
288 CharacterDatabase.CommitTransaction(trans);
289}
@ CHAR_DEL_GIFT
Definition: CharacterDatabase.h:130
void SetEntry(uint32 entry)
Definition: Object.h:113

References CHAR_DEL_GIFT, CharacterDatabase, Player::DestroyItem(), ObjectGuid::Empty, Field::Get(), Item::GetBagSlot(), ObjectGuid::GetCounter(), Object::GetGUID(), Player::GetItemByPos(), GetPlayer(), Item::GetSlot(), Item::GetTemplate(), Item::IsWrapped(), ITEM_CHANGED, ITEM_FIELD_FLAGS, ITEM_FIELD_GIFTCREATOR, ITEM_FIELD_MAXDURABILITY, LOG_ERROR, ItemTemplate::MaxDurability, Player::SaveInventoryAndGoldToDB(), PreparedStatementBase::SetData(), Object::SetEntry(), Object::SetGuidValue(), Item::SetState(), Object::SetUInt32Value(), and ObjectGuid::ToString().

Referenced by HandleOpenItemOpcode().

◆ HandleOptOutOfLootOpcode()

void WorldSession::HandleOptOutOfLootOpcode ( WorldPacket recvData)
1094{
1095 uint32 passOnLoot;
1096 recvData >> passOnLoot; // 1 always pass, 0 do not pass
1097
1098 if (!GetPlayer())
1099 return;
1100
1101 GetPlayer()->SetPassOnGroupLoot(passOnLoot);
1102}
void SetPassOnGroupLoot(bool bPassOnGroupLoot)
Definition: Player.h:2470

References GetPlayer(), and Player::SetPassOnGroupLoot().

Referenced by OpcodeTable::Initialize().

◆ HandlePageTextQueryOpcode()

void WorldSession::HandlePageTextQueryOpcode ( WorldPacket recvPacket)

Only static data is sent in this packet !!!

368{
369 uint32 pageID;
370 recvData >> pageID;
371 recvData.read_skip<uint64>(); // guid
372
373 while (pageID)
374 {
375 PageText const* pageText = sObjectMgr->GetPageText(pageID);
376 // guess size
378 data << pageID;
379
380 if (!pageText)
381 {
382 data << "Item page missing.";
383 data << uint32(0);
384 pageID = 0;
385 }
386 else
387 {
388 std::string Text = pageText->Text;
389
390 int loc_idx = GetSessionDbLocaleIndex();
391 if (loc_idx >= 0)
392 if (PageTextLocale const* player = sObjectMgr->GetPageTextLocale(pageID))
393 ObjectMgr::GetLocaleString(player->Text, loc_idx, Text);
394
395 data << Text;
396 data << uint32(pageText->NextPage);
397 pageID = pageText->NextPage;
398 }
399 SendPacket(&data);
400
401 LOG_DEBUG("network", "WORLD: Sent SMSG_PAGE_TEXT_QUERY_RESPONSE");
402 }
403}
Text
Definition: boss_pyroguard_emberseer.cpp:26
@ SMSG_PAGE_TEXT_QUERY_RESPONSE
Definition: Opcodes.h:121
Definition: ObjectMgr.h:58
uint16 NextPage
Definition: ObjectMgr.h:60
std::string Text
Definition: ObjectMgr.h:59
Definition: NPCHandler.h:50

References ObjectMgr::GetLocaleString(), GetSessionDbLocaleIndex(), LOG_DEBUG, PageText::NextPage, ByteBuffer::read_skip(), SendPacket(), SMSG_PAGE_TEXT_QUERY_RESPONSE, sObjectMgr, and PageText::Text.

Referenced by OpcodeTable::Initialize().

◆ HandlePartyAssignmentOpcode()

void WorldSession::HandlePartyAssignmentOpcode ( WorldPacket recvData)
679{
680 Group* group = GetPlayer()->GetGroup();
681 if (!group)
682 return;
683
684 ObjectGuid senderGuid = GetPlayer()->GetGUID();
685 if (!group->IsLeader(senderGuid) && !group->IsAssistant(senderGuid))
686 return;
687
688 uint8 assignment;
689 bool apply;
690 ObjectGuid guid;
691 recvData >> assignment >> apply;
692 recvData >> guid;
693
694 switch (assignment)
695 {
698 group->SetGroupMemberFlag(guid, apply, MEMBER_FLAG_MAINASSIST);
699 break;
701 group->RemoveUniqueGroupMemberFlag(MEMBER_FLAG_MAINTANK); // Remove main assist flag from current if any.
702 group->SetGroupMemberFlag(guid, apply, MEMBER_FLAG_MAINTANK);
703 default:
704 break;
705 }
706
707 group->SendUpdate();
708}
@ GROUP_ASSIGN_MAINASSIST
Definition: Group.h:81
@ GROUP_ASSIGN_MAINTANK
Definition: Group.h:80
@ MEMBER_FLAG_MAINASSIST
Definition: Group.h:75
@ MEMBER_FLAG_MAINTANK
Definition: Group.h:74
void RemoveUniqueGroupMemberFlag(GroupMemberFlags flag)
Definition: Group.cpp:2517

References Player::GetGroup(), Object::GetGUID(), GetPlayer(), GROUP_ASSIGN_MAINASSIST, GROUP_ASSIGN_MAINTANK, Group::IsAssistant(), Group::IsLeader(), MEMBER_FLAG_MAINASSIST, MEMBER_FLAG_MAINTANK, Group::RemoveUniqueGroupMemberFlag(), Group::SendUpdate(), and Group::SetGroupMemberFlag().

Referenced by OpcodeTable::Initialize().

◆ HandlePetAbandon()

void WorldSession::HandlePetAbandon ( WorldPackets::Pet::PetAbandon packet)
910{
911 if (!_player->IsInWorld())
912 return;
913
914 // pet/charmed
916 if (pet && pet->ToPet() && pet->ToPet()->getPetType() == HUNTER_PET)
917 {
918 if (pet->IsPet())
919 {
920 if (pet->GetGUID() == _player->GetPetGUID())
921 {
922 uint32 feelty = pet->GetPower(POWER_HAPPINESS);
923 pet->SetPower(POWER_HAPPINESS, feelty > 50000 ? (feelty - 50000) : 0);
924 }
925
927 }
928 else if (pet->GetGUID() == _player->GetCharmGUID())
930 }
931}
@ PET_SAVE_AS_DELETED
Definition: PetDefines.h:41
@ HUNTER_PET
Definition: PetDefines.h:32
@ POWER_HAPPINESS
Definition: SharedDefines.h:273
PetType getPetType() const
Definition: Pet.h:52
void RemovePet(Pet *pet, PetSaveMode mode, bool returnreagent=false)
Definition: Player.cpp:9057
void StopCastingCharm(Aura *except=nullptr)
Definition: Player.cpp:9294
Pet * ToPet()
Definition: Unit.h:1728
void SetPower(Powers power, uint32 val, bool withPowerUpdate=true, bool fromRegenerate=false)
Definition: Unit.cpp:15530
bool IsPet() const
Definition: Unit.h:710
ObjectGuid GetPetGUID() const
Definition: Unit.h:1232
ObjectGuid PetGUID
Definition: PetPackets.h:45

References _player, Unit::GetCharmGUID(), ObjectAccessor::GetCreatureOrPetOrVehicle(), Object::GetGUID(), Unit::GetPetGUID(), Pet::getPetType(), Unit::GetPower(), HUNTER_PET, Object::IsInWorld(), Unit::IsPet(), PET_SAVE_AS_DELETED, WorldPackets::Pet::PetAbandon::PetGUID, POWER_HAPPINESS, Player::RemovePet(), Unit::SetPower(), Player::StopCastingCharm(), and Unit::ToPet().

Referenced by OpcodeTable::Initialize().

◆ HandlePetAction()

void WorldSession::HandlePetAction ( WorldPacket recvData)
58{
59 ObjectGuid guid1;
60 uint32 data;
61 ObjectGuid guid2;
62 recvData >> guid1; //pet guid
63 recvData >> data;
64 recvData >> guid2; //tag guid
65
66 uint32 spellId = UNIT_ACTION_BUTTON_ACTION(data);
67 uint8 flag = UNIT_ACTION_BUTTON_TYPE(data); //delete = 0x07 CastSpell = C1
68
69 // used also for charmed creature
70 Unit* pet = ObjectAccessor::GetUnit(*_player, guid1);
71 LOG_DEBUG("network.opcode", "HandlePetAction: Pet {} - flag: {}, spellId: {}, target: {}.", guid1.ToString(), uint32(flag), spellId, guid2.ToString());
72
73 if (!pet)
74 {
75 LOG_ERROR("network.opcode", "HandlePetAction: Pet ({}) doesn't exist for player {}", guid1.ToString(), GetPlayer()->GetName());
76 return;
77 }
78
79 if (pet != GetPlayer()->GetFirstControlled())
80 {
81 LOG_ERROR("network.opcode", "HandlePetAction: Pet ({}) does not belong to player {}", guid1.ToString(), GetPlayer()->GetName());
82 return;
83 }
84
85 if (!pet->IsAlive())
86 {
87 // xinef: allow dissmis dead pets
88 SpellInfo const* spell = (flag == ACT_ENABLED || flag == ACT_PASSIVE) ? sSpellMgr->GetSpellInfo(spellId) : nullptr;
89 if ((flag != ACT_COMMAND || spellId != COMMAND_ABANDON) && (!spell || !spell->HasAttribute(SPELL_ATTR0_ALLOW_CAST_WHILE_DEAD)))
90 return;
91 }
92
93 // Xinef: allow to controll players
94 if (pet->IsPlayer() && flag != ACT_COMMAND && flag != ACT_REACTION)
95 return;
96
97 // Do not follow itself vehicle
98 if (spellId == COMMAND_FOLLOW && _player->IsOnVehicle(pet))
99 {
100 return;
101 }
102
103 if (GetPlayer()->m_Controlled.size() == 1)
104 HandlePetActionHelper(pet, guid1, spellId, flag, guid2);
105 else
106 {
107 //If a pet is dismissed, m_Controlled will change
108 std::vector<Unit*> controlled;
109 for (Unit::ControlSet::iterator itr = GetPlayer()->m_Controlled.begin(); itr != GetPlayer()->m_Controlled.end(); ++itr)
110 {
111 // xinef: allow to dissmis dead pets
112 if ((*itr)->GetEntry() == pet->GetEntry() && ((*itr)->IsAlive() || (flag == ACT_COMMAND && spellId == COMMAND_ABANDON)))
113 controlled.push_back(*itr);
114 // xinef: mirror image blizzard
115 else if ((*itr)->GetEntry() == NPC_MIRROR_IMAGE && flag == ACT_COMMAND && spellId == COMMAND_FOLLOW)
116 {
117 (*itr)->InterruptNonMeleeSpells(false);
118 }
119 }
120
121 for (Unit* pet : controlled)
122 if (pet && pet->IsInWorld() && pet->GetMap() == _player->GetMap())
123 HandlePetActionHelper(pet, guid1, spellId, flag, guid2);
124 }
125}
@ COMMAND_ABANDON
Definition: Unit.h:558
@ COMMAND_FOLLOW
Definition: Unit.h:556
#define UNIT_ACTION_BUTTON_ACTION(X)
Definition: CharmInfo.h:30
@ ACT_REACTION
Definition: CharmInfo.h:64
@ ACT_COMMAND
Definition: CharmInfo.h:63
@ ACT_ENABLED
Definition: CharmInfo.h:62
@ ACT_PASSIVE
Definition: CharmInfo.h:60
#define UNIT_ACTION_BUTTON_TYPE(X)
Definition: CharmInfo.h:31
@ NPC_MIRROR_IMAGE
Definition: PetDefines.h:105
@ SPELL_ATTR0_ALLOW_CAST_WHILE_DEAD
Definition: SharedDefines.h:405
ControlSet m_Controlled
Definition: Unit.h:1793
void HandlePetActionHelper(Unit *pet, ObjectGuid guid1, uint32 spellid, uint16 flag, ObjectGuid guid2)
Definition: PetHandler.cpp:150

References _player, ACT_COMMAND, ACT_ENABLED, ACT_PASSIVE, ACT_REACTION, COMMAND_ABANDON, COMMAND_FOLLOW, Object::GetEntry(), WorldObject::GetMap(), GetPlayer(), ObjectAccessor::GetUnit(), HandlePetActionHelper(), SpellInfo::HasAttribute(), Unit::IsAlive(), Object::IsInWorld(), Unit::IsOnVehicle(), Object::IsPlayer(), LOG_DEBUG, LOG_ERROR, Unit::m_Controlled, NPC_MIRROR_IMAGE, SPELL_ATTR0_ALLOW_CAST_WHILE_DEAD, sSpellMgr, ObjectGuid::ToString(), UNIT_ACTION_BUTTON_ACTION, and UNIT_ACTION_BUTTON_TYPE.

Referenced by OpcodeTable::Initialize().

◆ HandlePetActionHelper()

void WorldSession::HandlePetActionHelper ( Unit pet,
ObjectGuid  guid1,
uint32  spellid,
uint16  flag,
ObjectGuid  guid2 
)
Todo:
: Not sure whether the fallthrough was a mistake (forgetting a break) or intended. This should be double-checked.
151{
152 CharmInfo* charmInfo = pet->GetCharmInfo();
153 if (!charmInfo)
154 {
155 LOG_ERROR("network.opcode", "WorldSession::HandlePetAction(petGuid: {}, tagGuid: {}, spellId: {}, flag: {}): object ({}) is considered pet-like but doesn't have a charminfo!",
156 guid1.ToString(), guid2.ToString(), spellId, flag, pet->GetGUID().ToString());
157 return;
158 }
159
160 switch (flag)
161 {
162 case ACT_COMMAND: //0x07
163 switch (spellId)
164 {
165 case COMMAND_STAY: //flat=1792 //STAY
166 {
168 if (!controlledMotion)
169 {
171 pet->GetMotionMaster()->Clear(false);
172 pet->GetMotionMaster()->MoveIdle();
173 }
174
175 charmInfo->SetCommandState(COMMAND_STAY);
176 charmInfo->SetIsCommandAttack(false);
177 charmInfo->SetIsCommandFollow(false);
178 charmInfo->SetIsFollowing(false);
179 charmInfo->SetIsReturning(false);
180 charmInfo->SetIsAtStay(!controlledMotion);
181 charmInfo->SaveStayPosition(controlledMotion);
182 if (pet->ToPet())
184
185 charmInfo->SetForcedSpell(0);
186 charmInfo->SetForcedTargetGUID();
187 break;
188 }
189 case COMMAND_FOLLOW: //spellId=1792 //FOLLOW
190 {
191 pet->AttackStop();
192 pet->InterruptNonMeleeSpells(false);
193 pet->ClearInPetCombat();
195 if (pet->ToPet())
198
199 charmInfo->SetIsCommandAttack(false);
200 charmInfo->SetIsAtStay(false);
201 charmInfo->SetIsReturning(true);
202 charmInfo->SetIsCommandFollow(true);
203 charmInfo->SetIsFollowing(false);
204 charmInfo->RemoveStayPosition();
205 charmInfo->SetForcedSpell(0);
206 charmInfo->SetForcedTargetGUID();
207 break;
208 }
209 case COMMAND_ATTACK: //spellId=1792 //ATTACK
210 {
211 // Can't attack if owner is pacified
213 {
214 //pet->SendPetCastFail(spellId, SPELL_FAILED_PACIFIED);
215 //TODO: Send proper error message to client
216 return;
217 }
218
219 // only place where pet can be player
220 Unit* TargetUnit = ObjectAccessor::GetUnit(*_player, guid2);
221 if (!TargetUnit)
222 return;
223
224 if (Unit* owner = pet->GetOwner())
225 if (!owner->IsValidAttackTarget(TargetUnit))
226 return;
227
228 // pussywizard (excluded charmed)
229 if (!pet->IsCharmed())
230 if (Creature* creaturePet = pet->ToCreature())
231 if (!creaturePet->CanCreatureAttack(TargetUnit))
232 return;
233
234 // Not let attack through obstructions
235 bool checkLos = !DisableMgr::IsPathfindingEnabled(pet->GetMap()) ||
236 (TargetUnit->IsCreature() && (TargetUnit->ToCreature()->isWorldBoss() || TargetUnit->ToCreature()->IsDungeonBoss()));
237
238 if (checkLos && !pet->IsWithinLOSInMap(TargetUnit))
239 {
240 WorldPacket data(SMSG_CAST_FAILED, 1 + 4 + 1);
241 data << uint8(0);
242 data << uint32(7389);
244 SendPacket(&data);
245 return;
246 }
247
249 // This is true if pet has no target or has target but targets differs.
250 if (pet->GetVictim() != TargetUnit || (pet->GetVictim() == TargetUnit && !pet->GetCharmInfo()->IsCommandAttack()))
251 {
252 pet->AttackStop();
253
254 if (!pet->IsPlayer() && pet->ToCreature()->IsAIEnabled)
255 {
256 charmInfo->SetIsCommandAttack(true);
257 charmInfo->SetIsAtStay(false);
258 charmInfo->SetIsFollowing(false);
259 charmInfo->SetIsCommandFollow(false);
260 charmInfo->SetIsReturning(false);
261
262 pet->ToCreature()->AI()->AttackStart(TargetUnit);
263
264 //10% chance to play special pet attack talk, else growl
265 if (pet->IsPet() && ((Pet*)pet)->getPetType() == SUMMON_PET && pet != TargetUnit && urand(0, 100) < 10)
267 else
268 {
269 // 90% chance for pet and 100% chance for charmed creature
270 pet->SendPetAIReaction(guid1);
271 }
272 }
273 else // charmed player
274 {
275 charmInfo->SetIsCommandAttack(true);
276 charmInfo->SetIsAtStay(false);
277 charmInfo->SetIsFollowing(false);
278 charmInfo->SetIsCommandFollow(false);
279 charmInfo->SetIsReturning(false);
280
281 pet->Attack(TargetUnit, true);
282 pet->SendPetAIReaction(guid1);
283 }
284 }
285 break;
286 }
287 case COMMAND_ABANDON: // abandon (hunter pet) or dismiss (summoned pet)
288 if (pet->GetCharmerGUID() == GetPlayer()->GetGUID())
289 {
291 }
292 else if (pet->GetOwnerGUID() == GetPlayer()->GetGUID())
293 {
294 ASSERT(pet->IsCreature());
295 if (pet->IsPet())
296 {
297 if (pet->ToPet()->getPetType() == HUNTER_PET)
299 else
300 //dismissing a summoned pet is like killing them (this prevents returning a soulshard...)
301 pet->setDeathState(DeathState::Corpse);
302 }
304 {
305 pet->ToTempSummon()->UnSummon();
306 }
307 }
308 break;
309 default:
310 LOG_ERROR("network.opcode", "WORLD: unknown PET flag Action {} and spellId {}.", uint32(flag), spellId);
311 }
312 break;
313 case ACT_REACTION: // 0x6
314 switch (spellId)
315 {
316 case REACT_PASSIVE: //passive
317 pet->AttackStop();
318 if (pet->ToPet())
320 pet->ClearInPetCombat();
321 [[fallthrough]];
322
323 case REACT_DEFENSIVE: //recovery
324 case REACT_AGGRESSIVE: //activete
325 if (pet->IsCreature())
326 pet->ToCreature()->SetReactState(ReactStates(spellId));
327 else
328 charmInfo->SetPlayerReactState(ReactStates(spellId));
329 break;
330 }
331 break;
332 case ACT_DISABLED: // 0x81 spell (disabled), ignore
333 case ACT_PASSIVE: // 0x01
334 case ACT_ENABLED: // 0xC1 spell
335 {
336 Unit* unit_target = nullptr;
337
338 // do not cast unknown spells
339 SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(spellId);
340 if (!spellInfo)
341 {
342 LOG_ERROR("network.opcode", "WORLD: unknown PET spell id {}", spellId);
343 return;
344 }
345
346 if (guid2)
347 unit_target = ObjectAccessor::GetUnit(*_player, guid2);
348 else if (!spellInfo->IsPositive())
349 return;
350
351 for (uint32 i = 0; i < MAX_SPELL_EFFECTS; ++i)
352 {
353 if (spellInfo->Effects[i].TargetA.GetTarget() == TARGET_UNIT_SRC_AREA_ENEMY || spellInfo->Effects[i].TargetA.GetTarget() == TARGET_UNIT_DEST_AREA_ENEMY || spellInfo->Effects[i].TargetA.GetTarget() == TARGET_DEST_DYNOBJ_ENEMY)
354 return;
355 }
356
357 TriggerCastFlags triggerCastFlags = TRIGGERED_NONE;
358
359 if (spellInfo->IsPassive())
360 return;
361
362 // cast only learned spells
363 if (!pet->HasSpell(spellId))
364 {
365 bool allow = false;
366
367 // allow casting of spells triggered by clientside periodic trigger auras
369 {
370 allow = true;
371 triggerCastFlags = TRIGGERED_FULL_MASK;
372 }
373
374 if (!allow)
375 return;
376 }
377
378 Spell* spell = new Spell(pet, spellInfo, triggerCastFlags);
379 spell->LoadScripts(); // xinef: load for CheckPetCast
380
381 SpellCastResult result = spell->CheckPetCast(unit_target);
382
383 //auto turn to target unless possessed
384 if (result == SPELL_FAILED_UNIT_NOT_INFRONT && !pet->isPossessed() && !pet->IsVehicle())
385 {
386 if (unit_target)
387 {
388 pet->SetInFront(unit_target);
389 if (unit_target->IsPlayer())
390 pet->SendUpdateToPlayer(unit_target->ToPlayer());
391 }
392 else if (Unit* unit_target2 = spell->m_targets.GetUnitTarget())
393 {
394 pet->SetInFront(unit_target2);
395 if (unit_target2->IsPlayer())
396 pet->SendUpdateToPlayer(unit_target2->ToPlayer());
397 }
398 if (Unit* powner = pet->GetCharmerOrOwner())
399 if (powner->IsPlayer())
400 pet->SendUpdateToPlayer(powner->ToPlayer());
401
402 result = SPELL_CAST_OK;
403 }
404
405 if (result == SPELL_CAST_OK)
406 {
407 if (!spellInfo->IsCooldownStartedOnEvent())
408 {
409 pet->ToCreature()->AddSpellCooldown(spellId, 0, 0);
410 }
411
412 unit_target = spell->m_targets.GetUnitTarget();
413
414 //10% chance to play special pet attack talk, else growl
415 //actually this only seems to happen on special spells, fire shield for imp, torment for voidwalker, but it's stupid to check every spell
416 if (pet->IsPet() && (((Pet*)pet)->getPetType() == SUMMON_PET) && (pet != unit_target) && (urand(0, 100) < 10))
418 else
419 {
420 pet->SendPetAIReaction(guid1);
421 }
422
423 if (unit_target && !GetPlayer()->IsFriendlyTo(unit_target) && !pet->isPossessed() && !pet->IsVehicle())
424 {
425 // This is true if pet has no target or has target but targets differs.
426 if (pet->GetVictim() != unit_target)
427 {
428 if (pet->ToCreature()->IsAIEnabled)
429 pet->ToCreature()->AI()->AttackStart(unit_target);
430 }
431 }
432
433 spell->prepare(&(spell->m_targets));
434
435 charmInfo->SetForcedSpell(0);
436 charmInfo->SetForcedTargetGUID();
437 }
438 else if (pet->ToPet() && (result == SPELL_FAILED_LINE_OF_SIGHT || result == SPELL_FAILED_OUT_OF_RANGE))
439 {
440 unit_target = spell->m_targets.GetUnitTarget();
441 bool haspositiveeffect = false;
442
443 if (!unit_target)
444 return;
445
446 // search positive effects for spell
447 for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
448 {
449 if (spellInfo->_IsPositiveEffect(i, true))
450 {
451 haspositiveeffect = true;
452 break;
453 }
454 }
455
456 if (pet->isPossessed() || pet->IsVehicle())
457 Spell::SendCastResult(GetPlayer(), spellInfo, 0, result);
458 else if (GetPlayer()->IsFriendlyTo(unit_target) && !haspositiveeffect)
460 else
462
463 if (!pet->HasSpellCooldown(spellId))
464 if (pet->ToPet())
465 pet->ToPet()->RemoveSpellCooldown(spellId, true);
466
467 spell->finish(false);
468 delete spell;
469
471 return;
472
473 bool tempspellIsPositive = false;
474
475 if (!GetPlayer()->IsFriendlyTo(unit_target))
476 {
477 // only place where pet can be player
478 Unit* TargetUnit = ObjectAccessor::GetUnit(*_player, guid2);
479 if (!TargetUnit)
480 return;
481
482 if (Unit* owner = pet->GetOwner())
483 if (!owner->IsValidAttackTarget(TargetUnit))
484 return;
485
487 // This is true if pet has no target or has target but targets differs.
488 if (pet->GetVictim() != TargetUnit || (pet->GetVictim() == TargetUnit && !pet->GetCharmInfo()->IsCommandAttack()))
489 {
490 if (pet->GetVictim())
491 pet->AttackStop();
492
493 if (!pet->IsPlayer() && pet->ToCreature() && pet->ToCreature()->IsAIEnabled)
494 {
495 charmInfo->SetIsCommandAttack(true);
496 charmInfo->SetIsAtStay(false);
497 charmInfo->SetIsFollowing(false);
498 charmInfo->SetIsCommandFollow(false);
499 charmInfo->SetIsReturning(false);
500
501 pet->ToCreature()->AI()->AttackStart(TargetUnit);
502
503 if (pet->IsPet() && ((Pet*)pet)->getPetType() == SUMMON_PET && pet != TargetUnit && urand(0, 100) < 10)
505 else
506 pet->SendPetAIReaction(guid1);
507 }
508 else // charmed player
509 {
510 if (pet->GetVictim() && pet->GetVictim() != TargetUnit)
511 pet->AttackStop();
512
513 charmInfo->SetIsCommandAttack(true);
514 charmInfo->SetIsAtStay(false);
515 charmInfo->SetIsFollowing(false);
516 charmInfo->SetIsCommandFollow(false);
517 charmInfo->SetIsReturning(false);
518
519 pet->Attack(TargetUnit, true);
520 pet->SendPetAIReaction(guid1);
521 }
522
523 pet->ToPet()->CastWhenWillAvailable(spellId, unit_target, ObjectGuid::Empty, tempspellIsPositive);
524 }
525 }
526 else if (haspositiveeffect)
527 {
528 bool tmpSpellIsPositive = true;
530 // This is true if pet has no target or has target but targets differs.
531 Unit* victim = pet->GetVictim();
532 if (victim)
533 {
534 pet->AttackStop();
535 }
536 else
537 victim = nullptr;
538
539 if (!pet->IsPlayer() && pet->ToCreature() && pet->ToCreature()->IsAIEnabled)
540 {
541 pet->StopMoving();
542 pet->GetMotionMaster()->Clear();
543
544 charmInfo->SetIsCommandAttack(false);
545 charmInfo->SetIsAtStay(false);
546 charmInfo->SetIsFollowing(false);
547 charmInfo->SetIsCommandFollow(false);
548 charmInfo->SetIsReturning(false);
549
550 pet->GetMotionMaster()->MoveFollow(unit_target, PET_FOLLOW_DIST, rand_norm() * 2 * M_PI);
551
552 if (pet->IsPet() && ((Pet*)pet)->getPetType() == SUMMON_PET && pet != unit_target && urand(0, 100) < 10)
554 else
555 {
556 pet->SendPetAIReaction(guid1);
557 }
558
559 ObjectGuid oldTarget = ObjectGuid::Empty;
560 if (victim)
561 oldTarget = victim->GetGUID();
562
563 pet->ToPet()->CastWhenWillAvailable(spellId, unit_target, oldTarget, tmpSpellIsPositive);
564 }
565 }
566 }
567 else
568 {
569 // dont spam alerts
570 if (!charmInfo->GetForcedSpell())
571 {
572 if (pet->isPossessed() || pet->IsVehicle())
573 Spell::SendCastResult(GetPlayer(), spellInfo, 0, result);
574 else
575 spell->SendPetCastResult(result);
576 }
577
578 if (!pet->ToCreature()->HasSpellCooldown(spellId))
579 GetPlayer()->SendClearCooldown(spellId, pet);
580
581 spell->finish(false);
582 delete spell;
583
584 // reset specific flags in case of spell fail. AI will reset other flags
585 pet->PetSpellFail(spellInfo, unit_target, result);
586 }
587 break;
588 }
589 default:
590 LOG_ERROR("network.opcode", "WORLD: unknown PET flag Action {} and spellId {}.", uint32(flag), spellId);
591 }
592}
uint32 urand(uint32 min, uint32 max)
Definition: Random.cpp:44
double rand_norm()
Definition: Random.cpp:77
@ MOTION_SLOT_CONTROLLED
Definition: MotionMaster.h:63
@ NULL_MOTION_TYPE
Definition: MotionMaster.h:56
ReactStates
Definition: Unit.h:547
@ REACT_DEFENSIVE
Definition: Unit.h:549
@ REACT_PASSIVE
Definition: Unit.h:548
@ REACT_AGGRESSIVE
Definition: Unit.h:550
@ COMMAND_ATTACK
Definition: Unit.h:557
@ COMMAND_STAY
Definition: Unit.h:555
@ ACT_DISABLED
Definition: CharmInfo.h:61
@ UNIT_MASK_CONTROLABLE_GUARDIAN
Definition: UnitDefines.h:143
@ UNIT_MASK_SUMMON
Definition: UnitDefines.h:135
@ UNIT_MASK_GUARDIAN
Definition: UnitDefines.h:137
@ UNIT_MASK_MINION
Definition: UnitDefines.h:136
@ UNIT_STATE_FOLLOW
Definition: UnitDefines.h:158
#define PET_FOLLOW_DIST
Definition: PetDefines.h:198
@ SUMMON_PET
Definition: PetDefines.h:31
@ PET_TALK_SPECIAL_SPELL
Definition: PetDefines.h:80
@ PET_TALK_ATTACK
Definition: PetDefines.h:81
@ SPELL_AURA_MOD_PACIFY
Definition: SpellAuraDefines.h:88
@ SPELL_AURA_PERIODIC_TRIGGER_SPELL_FROM_CLIENT
Definition: SpellAuraDefines.h:111
@ TARGET_DEST_DYNOBJ_ENEMY
Definition: SharedDefines.h:1432
@ TARGET_UNIT_DEST_AREA_ENEMY
Definition: SharedDefines.h:1421
@ TARGET_UNIT_SRC_AREA_ENEMY
Definition: SharedDefines.h:1420
@ SPELL_FAILED_UNIT_NOT_INFRONT
Definition: SharedDefines.h:1083
@ SPELL_FAILED_OUT_OF_RANGE
Definition: SharedDefines.h:1046
@ SPELL_FAILED_DONT_REPORT
Definition: SharedDefines.h:976
@ SPELL_FAILED_LINE_OF_SIGHT
Definition: SharedDefines.h:996
@ SPELL_FAILED_TARGET_FRIENDLY
Definition: SharedDefines.h:1064
#define MAX_SPELL_EFFECTS
Definition: DBCStructure.h:1636
@ SMSG_CAST_FAILED
Definition: Opcodes.h:334
bool IsPathfindingEnabled(const Map *map)
Definition: DisableMgr.cpp:411
virtual void AttackStart(Unit *)
Definition: UnitAI.cpp:27
bool IsDungeonBoss() const
Definition: Creature.cpp:3161
bool isWorldBoss() const
Definition: Creature.h:123
bool HasSpellCooldown(uint32 spell_id) const override
Definition: Creature.cpp:2914
void AddSpellCooldown(uint32 spell_id, uint32, uint32 end_time, bool needSendToClient=false, bool forceSendToSpectator=false) override
Definition: Creature.cpp:2859
void SetReactState(ReactStates state)
A creature can have 3 ReactStates : Agressive, Passive, Neutral.
Definition: Creature.h:97
bool IsWithinLOSInMap(WorldObject const *obj, VMAP::ModelIgnoreFlags ignoreFlags=VMAP::ModelIgnoreFlags::Nothing, LineOfSightChecks checks=LINEOFSIGHT_ALL_CHECKS, Optional< float > collisionHeight={ }, Optional< float > combatReach={ }) const
Definition: Object.cpp:1347
void ClearCastWhenWillAvailable()
Definition: Pet.cpp:2450
Player * GetOwner() const
Definition: Pet.cpp:2493
void setDeathState(DeathState s, bool despawn=false) override
A creature can be in 4 different states: Alive, JustDied, Corpse, and JustRespawned....
Definition: Pet.cpp:631
void RemoveSpellCooldown(uint32 spell_id, bool update)
Definition: Pet.cpp:2458
void CastWhenWillAvailable(uint32 spellid, Unit *spellTarget, ObjectGuid oldTarget, bool spellIsPositive=false)
Definition: Pet.cpp:2434
bool HasSpell(uint32 spell) const override
Definition: Pet.cpp:2340
void SendClearCooldown(uint32 spell_id, Unit *target)
Definition: Player.cpp:14654
Definition: CharmInfo.h:125
void RemoveStayPosition()
Definition: CharmInfo.cpp:361
int32 GetForcedSpell()
Definition: CharmInfo.h:176
void SetIsCommandFollow(bool val)
Definition: CharmInfo.cpp:321
bool IsCommandAttack()
Definition: CharmInfo.cpp:316
void SetIsAtStay(bool val)
Definition: CharmInfo.cpp:373
void SetIsFollowing(bool val)
Definition: CharmInfo.cpp:383
void SetIsReturning(bool val)
Definition: CharmInfo.cpp:393
void SaveStayPosition(bool atCurrentPos)
Definition: CharmInfo.cpp:331
void SetForcedSpell(uint32 id)
Definition: CharmInfo.h:175
void SetPlayerReactState(ReactStates s)
Definition: CharmInfo.h:181
void SetForcedTargetGUID(ObjectGuid guid=ObjectGuid::Empty)
Definition: CharmInfo.h:177
void SetCommandState(CommandStates st)
Definition: CharmInfo.h:133
void SetIsCommandAttack(bool val)
Definition: CharmInfo.cpp:311
void ClearUnitState(uint32 f)
Definition: Unit.h:674
bool IsVehicle() const
Definition: Unit.h:713
Unit * GetOwner() const
Definition: Unit.cpp:10569
void PetSpellFail(SpellInfo const *spellInfo, Unit *target, uint32 result)
Definition: Unit.cpp:20319
void StopMoving()
Definition: Unit.cpp:16615
CharmInfo * GetCharmInfo()
Definition: Unit.h:1290
Unit * GetCharmerOrOwner() const
Definition: Unit.h:1255
void ClearInPetCombat()
Definition: Unit.cpp:13808
bool isPossessed() const
Definition: Unit.h:1279
void SendPetTalk(uint32 pettalk)
Definition: Unit.cpp:16584
void SendPetAIReaction(ObjectGuid guid)
Definition: Unit.cpp:16596
virtual float GetFollowAngle() const
Definition: Unit.h:1722
Unit * GetVictim() const
Definition: Unit.h:789
void StopMovingOnCurrentPos()
Definition: Unit.cpp:16654
bool IsAIEnabled
Definition: Unit.h:1818
ObjectGuid GetOwnerGUID() const
Definition: Unit.h:1222
uint32 HasUnitTypeMask(uint32 mask) const
Definition: Unit.h:677
ObjectGuid GetCharmerGUID() const
Definition: Unit.h:1228
bool HasAuraTypeWithTriggerSpell(AuraType auratype, uint32 triggerSpell) const
Definition: Unit.cpp:5734
void SetInFront(WorldObject const *target)
Definition: Unit.cpp:20496
MovementGeneratorType GetMotionSlotType(int slot) const
Definition: MotionMaster.cpp:921
void MoveFollow(Unit *target, float dist, float angle, MovementSlot slot=MOTION_SLOT_ACTIVE, bool inheritWalkState=true)
The unit will follow this target. Doesn't work with UNIT_FLAG_DISABLE_MOVE.
Definition: MotionMaster.cpp:409
void MoveIdle()
Definition: MotionMaster.cpp:232
void Clear(bool reset=true)
Definition: MotionMaster.h:165
void LoadScripts()
Definition: Spell.cpp:8494
void SendPetCastResult(SpellCastResult result)
Definition: Spell.cpp:4696
SpellCastResult CheckPetCast(Unit *target)
Definition: Spell.cpp:6812
void finish(bool ok=true)
Definition: Spell.cpp:4480
bool IsCooldownStartedOnEvent() const
Definition: SpellInfo.cpp:1211
bool _IsPositiveEffect(uint8 effIndex, bool deep) const
Definition: SpellInfo.cpp:2619

References SpellInfo::_IsPositiveEffect(), _player, ACT_COMMAND, ACT_DISABLED, ACT_ENABLED, ACT_PASSIVE, ACT_REACTION, Creature::AddSpellCooldown(), Creature::AI(), ASSERT, Unit::Attack(), UnitAI::AttackStart(), Unit::AttackStop(), Pet::CastWhenWillAvailable(), Spell::CheckPetCast(), MotionMaster::Clear(), Pet::ClearCastWhenWillAvailable(), Unit::ClearInPetCombat(), Unit::ClearUnitState(), COMMAND_ABANDON, COMMAND_ATTACK, COMMAND_FOLLOW, COMMAND_STAY, SpellInfo::Effects, ObjectGuid::Empty, Spell::finish(), Unit::GetCharmerGUID(), Unit::GetCharmerOrOwner(), Unit::GetCharmInfo(), Unit::GetFollowAngle(), CharmInfo::GetForcedSpell(), Object::GetGUID(), WorldObject::GetMap(), Unit::GetMotionMaster(), MotionMaster::GetMotionSlotType(), Unit::GetOwner(), Unit::GetOwnerGUID(), Pet::getPetType(), GetPlayer(), ObjectAccessor::GetUnit(), SpellCastTargets::GetUnitTarget(), Unit::GetVictim(), Unit::HasAuraType(), Unit::HasAuraTypeWithTriggerSpell(), Unit::HasSpell(), Creature::HasSpellCooldown(), Unit::HasSpellCooldown(), Unit::HasUnitTypeMask(), HUNTER_PET, Unit::InterruptNonMeleeSpells(), Unit::IsAIEnabled, Unit::IsCharmed(), CharmInfo::IsCommandAttack(), SpellInfo::IsCooldownStartedOnEvent(), Object::IsCreature(), Creature::IsDungeonBoss(), SpellInfo::IsPassive(), DisableMgr::IsPathfindingEnabled(), Unit::IsPet(), Object::IsPlayer(), SpellInfo::IsPositive(), Unit::isPossessed(), Unit::IsVehicle(), WorldObject::IsWithinLOSInMap(), Creature::isWorldBoss(), Spell::LoadScripts(), LOG_ERROR, Spell::m_targets, MAX_SPELL_EFFECTS, MOTION_SLOT_CONTROLLED, MotionMaster::MoveFollow(), MotionMaster::MoveIdle(), NULL_MOTION_TYPE, PET_FOLLOW_DIST, PET_SAVE_AS_DELETED, PET_TALK_ATTACK, PET_TALK_SPECIAL_SPELL, Unit::PetSpellFail(), Spell::prepare(), rand_norm(), REACT_AGGRESSIVE, REACT_DEFENSIVE, REACT_PASSIVE, Player::RemovePet(), Pet::RemoveSpellCooldown(), CharmInfo::RemoveStayPosition(), CharmInfo::SaveStayPosition(), Spell::SendCastResult(), Player::SendClearCooldown(), SendPacket(), Unit::SendPetAIReaction(), Spell::SendPetCastResult(), Unit::SendPetTalk(), Object::SendUpdateToPlayer(), CharmInfo::SetCommandState(), Unit::setDeathState(), CharmInfo::SetForcedSpell(), CharmInfo::SetForcedTargetGUID(), Unit::SetInFront(), CharmInfo::SetIsAtStay(), CharmInfo::SetIsCommandAttack(), CharmInfo::SetIsCommandFollow(), CharmInfo::SetIsFollowing(), CharmInfo::SetIsReturning(), CharmInfo::SetPlayerReactState(), Creature::SetReactState(), SMSG_CAST_FAILED, SPELL_AURA_MOD_PACIFY, SPELL_AURA_PERIODIC_TRIGGER_SPELL_FROM_CLIENT, SPELL_CAST_OK, SPELL_FAILED_DONT_REPORT, SPELL_FAILED_LINE_OF_SIGHT, SPELL_FAILED_OUT_OF_RANGE, SPELL_FAILED_TARGET_FRIENDLY, SPELL_FAILED_UNIT_NOT_INFRONT, sSpellMgr, Player::StopCastingCharm(), Unit::StopMoving(), Unit::StopMovingOnCurrentPos(), SUMMON_PET, TARGET_DEST_DYNOBJ_ENEMY, TARGET_UNIT_DEST_AREA_ENEMY, TARGET_UNIT_SRC_AREA_ENEMY, Object::ToCreature(), Unit::ToPet(), Object::ToPlayer(), ObjectGuid::ToString(), Unit::ToTempSummon(), TRIGGERED_FULL_MASK, TRIGGERED_NONE, UNIT_MASK_CONTROLABLE_GUARDIAN, UNIT_MASK_GUARDIAN, UNIT_MASK_MINION, UNIT_MASK_SUMMON, UNIT_STATE_FOLLOW, TempSummon::UnSummon(), and urand().

Referenced by HandlePetAction(), and PetAI::UpdateAI().

◆ HandlePetCancelAuraOpcode()

void WorldSession::HandlePetCancelAuraOpcode ( WorldPacket recvPacket)
528{
529 ObjectGuid guid;
530 uint32 spellId;
531
532 recvPacket >> guid;
533 recvPacket >> spellId;
534
535 SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(spellId);
536 if (!spellInfo)
537 {
538 LOG_ERROR("network.opcode", "WORLD: unknown PET spell id {}", spellId);
539 return;
540 }
541
543
544 if (!pet)
545 {
546 LOG_ERROR("network.opcode", "HandlePetCancelAura: Attempt to cancel an aura for non-existant pet {} by player {}", guid.ToString(), GetPlayer()->GetName());
547 return;
548 }
549
550 if (pet != GetPlayer()->GetGuardianPet() && pet != GetPlayer()->GetCharm())
551 {
552 LOG_ERROR("network.opcode", "HandlePetCancelAura: Pet {} is not a pet of player {}", guid.ToString(), GetPlayer()->GetName());
553 return;
554 }
555
556 if (!pet->IsAlive())
557 {
559 return;
560 }
561
563}
@ FEEDBACK_PET_DEAD
Definition: PetDefines.h:73
void SendPetActionFeedback(uint8 msg)
-------—Pet responses methods--------------—
Definition: Unit.cpp:16573

References _player, AURA_REMOVE_BY_CANCEL, ObjectGuid::Empty, FEEDBACK_PET_DEAD, ObjectAccessor::GetCreatureOrPetOrVehicle(), GetPlayer(), Unit::IsAlive(), LOG_ERROR, Unit::RemoveOwnedAura(), Unit::SendPetActionFeedback(), sSpellMgr, and ObjectGuid::ToString().

Referenced by OpcodeTable::Initialize().

◆ HandlePetCastSpellOpcode()

void WorldSession::HandlePetCastSpellOpcode ( WorldPacket recvPacket)
990{
991 LOG_DEBUG("network", "WORLD: CMSG_PET_CAST_SPELL");
992
993 ObjectGuid guid;
994 uint8 castCount;
995 uint32 spellId;
996 uint8 castFlags;
997
998 recvPacket >> guid >> castCount >> spellId >> castFlags;
999
1000 LOG_DEBUG("network", "WORLD: CMSG_PET_CAST_SPELL, guid: {}, castCount: {}, spellId {}, castFlags {}", guid.ToString(), castCount, spellId, castFlags);
1001
1002 // This opcode is also sent from charmed and possessed units (players and creatures)
1003 if (!_player->GetGuardianPet() && !_player->GetCharm())
1004 return;
1005
1006 Unit* caster = ObjectAccessor::GetUnit(*_player, guid);
1007
1008 if (!caster || (caster != _player->GetGuardianPet() && caster != _player->GetCharm()))
1009 {
1010 LOG_ERROR("network.opcode", "HandlePetCastSpellOpcode: Pet {} isn't pet of player {} .", guid.ToString(), GetPlayer()->GetName());
1011 return;
1012 }
1013
1014 SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(spellId);
1015 if (!spellInfo)
1016 {
1017 LOG_ERROR("network.opcode", "WORLD: unknown PET spell id {}", spellId);
1018 return;
1019 }
1020
1021 // do not cast not learned spells
1022 if (!caster->HasSpell(spellId) || spellInfo->IsPassive())
1023 return;
1024
1025 SpellCastTargets targets;
1026 targets.Read(recvPacket, caster);
1027 HandleClientCastFlags(recvPacket, castFlags, targets);
1028
1029 bool SetFollow = caster->HasUnitState(UNIT_STATE_FOLLOW);
1031
1032 Spell* spell = new Spell(caster, spellInfo, TRIGGERED_NONE);
1033 spell->m_cast_count = castCount; // probably pending spell cast
1034 spell->m_targets = targets;
1035 spell->LoadScripts();
1036
1037 // Xinef: Send default target, fixes return on NeedExplicitUnitTarget
1038 Unit* target = targets.GetUnitTarget();
1039 if (!target && spell->m_spellInfo->NeedsExplicitUnitTarget())
1040 target = _player->GetSelectedUnit();
1041
1042 SpellCastResult result = spell->CheckPetCast(target);
1043
1044 if (result == SPELL_CAST_OK)
1045 {
1046 if (Creature* creature = caster->ToCreature())
1047 {
1048 creature->AddSpellCooldown(spellId, 0, 0);
1049 if (Pet* pet = creature->ToPet())
1050 {
1051 // 10% chance to play special pet attack talk, else growl
1052 // actually this only seems to happen on special spells, fire shield for imp, torment for voidwalker, but it's stupid to check every spell
1053 if (pet->getPetType() == SUMMON_PET && (urand(0, 100) < 10))
1054 pet->SendPetTalk(PET_TALK_SPECIAL_SPELL);
1055 else
1056 pet->SendPetAIReaction(guid);
1057 }
1058 }
1059
1060 spell->prepare(&(spell->m_targets));
1061 }
1062 else
1063 {
1064 if (!caster->GetCharmInfo() || !caster->GetCharmInfo()->GetForcedSpell())
1065 spell->SendPetCastResult(result);
1066
1067 if (caster->IsPlayer())
1068 {
1069 if (!caster->ToPlayer()->HasSpellCooldown(spellId))
1070 GetPlayer()->SendClearCooldown(spellId, caster);
1071 }
1072 else
1073 {
1074 if (!caster->ToCreature()->HasSpellCooldown(spellId))
1075 GetPlayer()->SendClearCooldown(spellId, caster);
1076
1077 // reset specific flags in case of spell fail. AI will reset other flags
1078 if (caster->IsPet())
1079 caster->PetSpellFail(spellInfo, targets.GetUnitTarget(), result);
1080 }
1081
1082 spell->finish(false);
1083 delete spell;
1084 }
1085
1086 if (SetFollow && !caster->IsInCombat())
1088}
bool HasSpellCooldown(uint32 spell_id) const override
Definition: Player.cpp:16337
Unit * GetSelectedUnit() const
Definition: Player.cpp:11538
Unit * GetCharm() const
Definition: Unit.cpp:10635
virtual bool HasSpell(uint32) const
Definition: Unit.h:1111
void AddUnitState(uint32 f)
Definition: Unit.h:672
Guardian * GetGuardianPet() const
Definition: Unit.cpp:10620
bool NeedsExplicitUnitTarget() const
Definition: SpellInfo.cpp:1032

References _player, Unit::AddUnitState(), Spell::CheckPetCast(), Unit::ClearUnitState(), Spell::finish(), Unit::GetCharm(), Unit::GetCharmInfo(), CharmInfo::GetForcedSpell(), Unit::GetGuardianPet(), GetPlayer(), Player::GetSelectedUnit(), ObjectAccessor::GetUnit(), SpellCastTargets::GetUnitTarget(), HandleClientCastFlags(), Unit::HasSpell(), Creature::HasSpellCooldown(), Player::HasSpellCooldown(), Unit::HasUnitState(), Unit::IsInCombat(), SpellInfo::IsPassive(), Unit::IsPet(), Object::IsPlayer(), Spell::LoadScripts(), LOG_DEBUG, LOG_ERROR, Spell::m_cast_count, Spell::m_spellInfo, Spell::m_targets, SpellInfo::NeedsExplicitUnitTarget(), PET_TALK_SPECIAL_SPELL, Unit::PetSpellFail(), Spell::prepare(), SpellCastTargets::Read(), Player::SendClearCooldown(), Spell::SendPetCastResult(), SPELL_CAST_OK, sSpellMgr, SUMMON_PET, Object::ToCreature(), Unit::ToPet(), Object::ToPlayer(), ObjectGuid::ToString(), TRIGGERED_NONE, UNIT_STATE_FOLLOW, and urand().

Referenced by OpcodeTable::Initialize().

◆ HandlePetitionBuyOpcode()

void WorldSession::HandlePetitionBuyOpcode ( WorldPacket recvData)
Todo:
: find correct opcode
33{
34 LOG_DEBUG("network", "Received opcode CMSG_PETITION_BUY");
35
36 ObjectGuid guidNPC;
37 uint32 clientIndex; // 1 for guild and arenaslot+1 for arenas in client
38 std::string name;
39
40 recvData >> guidNPC; // NPC GUID
41 recvData.read_skip<uint32>(); // 0
42 recvData.read_skip<uint64>(); // 0
43 recvData >> name; // name
44 recvData.read_skip<std::string>(); // some string
45 recvData.read_skip<uint32>(); // 0
46 recvData.read_skip<uint32>(); // 0
47 recvData.read_skip<uint32>(); // 0
48 recvData.read_skip<uint32>(); // 0
49 recvData.read_skip<uint32>(); // 0
50 recvData.read_skip<uint32>(); // 0
51 recvData.read_skip<uint32>(); // 0
52 recvData.read_skip<uint16>(); // 0
53 recvData.read_skip<uint32>(); // 0
54 recvData.read_skip<uint32>(); // 0
55 recvData.read_skip<uint32>(); // 0
56
57 for (int i = 0; i < 10; ++i)
58 recvData.read_skip<std::string>();
59
60 recvData >> clientIndex; // index
61 recvData.read_skip<uint32>(); // 0
62
63 LOG_DEBUG("network", "Petitioner ({}) tried sell petition: name {}", guidNPC.ToString(), name);
64
65 // prevent cheating
67 if (!creature)
68 {
69 LOG_DEBUG("network", "WORLD: HandlePetitionBuyOpcode - Unit ({}) not found or you can't interact with him.", guidNPC.ToString());
70 return;
71 }
72
73 // remove fake death
74 if (GetPlayer()->HasUnitState(UNIT_STATE_DIED))
76
77 uint32 charterid = 0;
78 uint32 cost = 0;
79 uint32 type = 0;
80 if (creature->IsTabardDesigner())
81 {
82 // if tabard designer, then trying to buy a guild charter.
83 // do not let if already in guild.
84 if (_player->GetGuildId())
85 return;
86
87 charterid = GUILD_CHARTER;
88 cost = sWorld->getIntConfig(CONFIG_CHARTER_COST_GUILD);
89 type = GUILD_CHARTER_TYPE;
90 }
91 else
92 {
94 if (_player->GetLevel() < sWorld->getIntConfig(CONFIG_MAX_PLAYER_LEVEL))
95 {
97 return;
98 }
99
100 switch (clientIndex) // arenaSlot+1 as received from client (1 from 3 case)
101 {
102 case 1:
103 charterid = ARENA_TEAM_CHARTER_2v2;
104 cost = sWorld->getIntConfig(CONFIG_CHARTER_COST_ARENA_2v2);
106 break;
107 case 2:
108 charterid = ARENA_TEAM_CHARTER_3v3;
109 cost = sWorld->getIntConfig(CONFIG_CHARTER_COST_ARENA_3v3);
111 break;
112 case 3:
113 charterid = ARENA_TEAM_CHARTER_5v5;
114 cost = sWorld->getIntConfig(CONFIG_CHARTER_COST_ARENA_5v5);
116 break;
117 default:
118 LOG_DEBUG("network", "unknown selection at buy arena petition: {}", clientIndex);
119 return;
120 }
121
122 if (_player->GetArenaTeamId(clientIndex - 1)) // arenaSlot+1 as received from client
123 {
125 return;
126 }
127 }
128
129 sScriptMgr->PetitionBuy(_player, creature, charterid, cost, type);
130
131 if (type == GUILD_CHARTER_TYPE)
132 {
133 if (sGuildMgr->GetGuildByName(name))
134 {
136 return;
137 }
138
140 {
142 return;
143 }
144 }
145 else
146 {
147 if (sArenaTeamMgr->GetArenaTeamByName(name))
148 {
150 return;
151 }
153 {
155 return;
156 }
157 }
158
159 ItemTemplate const* pProto = sObjectMgr->GetItemTemplate(charterid);
160 if (!pProto)
161 {
162 _player->SendBuyError(BUY_ERR_CANT_FIND_ITEM, nullptr, charterid, 0);
163 return;
164 }
165
166 if (!_player->HasEnoughMoney(cost))
167 {
168 //player hasn't got enough money
169 _player->SendBuyError(BUY_ERR_NOT_ENOUGHT_MONEY, creature, charterid, 0);
170 return;
171 }
172
173 ItemPosCountVec dest;
174 InventoryResult msg = _player->CanStoreNewItem(NULL_BAG, NULL_SLOT, dest, charterid, pProto->BuyCount);
175 if (msg != EQUIP_ERR_OK)
176 {
177 _player->SendEquipError(msg, nullptr, nullptr, charterid);
178 return;
179 }
180
181 _player->ModifyMoney(-(int32)cost);
182 Item* charter = _player->StoreNewItem(dest, charterid, true);
183 if (!charter)
184 return;
185
187 // ITEM_FIELD_ENCHANTMENT_1_1 is guild/arenateam id
188 // ITEM_FIELD_ENCHANTMENT_1_1+1 is current signatures count (showed on item)
189 charter->SetState(ITEM_CHANGED, _player);
190 _player->SendNewItem(charter, 1, true, false);
191
192 // a petition is invalid, if both the owner and the type matches
193 // we checked above, if this player is in an arenateam, so this must be
194 // datacorruption
195 Petition const* petition = sPetitionMgr->GetPetitionByOwnerWithType(_player->GetGUID(), type);
196
197 CharacterDatabase.EscapeString(name);
198 CharacterDatabaseTransaction trans = CharacterDatabase.BeginTransaction();
199
200 if (petition)
201 {
202 LOG_DEBUG("network", "Invalid petition: {}", petition->petitionGuid.ToString());
203
204 trans->Append("DELETE FROM petition WHERE petitionguid = {}", petition->petitionGuid.GetCounter());
205 trans->Append("DELETE FROM petition_sign WHERE petitionguid = {}", petition->petitionGuid.GetCounter());
206
207 // xinef: clear petition store
208 sPetitionMgr->RemovePetition(petition->petitionGuid);
209 }
210
211 // xinef: petition pointer is invalid from now on
212
214 stmt->SetData(0, _player->GetGUID().GetCounter());
215 stmt->SetData(1, charter->GetGUID().GetCounter());
216 stmt->SetData(2, name);
217 stmt->SetData(3, uint8(type));
218 trans->Append(stmt);
219
220 CharacterDatabase.CommitTransaction(trans);
221
222 // xinef: fill petition store
223 sPetitionMgr->AddPetition(charter->GetGUID(), _player->GetGUID(), name, uint8(type));
224}
@ ERR_ARENA_TEAM_NAME_INVALID
Definition: ArenaTeam.h:45
@ ERR_ARENA_TEAM_NAME_EXISTS_S
Definition: ArenaTeam.h:46
@ ERR_GUILD_NAME_EXISTS_S
Definition: Guild.h:129
@ ERR_GUILD_NAME_INVALID
Definition: Guild.h:128
@ CONFIG_CHARTER_COST_GUILD
Definition: IWorld.h:395
@ CONFIG_CHARTER_COST_ARENA_5v5
Definition: IWorld.h:398
@ CONFIG_CHARTER_COST_ARENA_2v2
Definition: IWorld.h:396
@ CONFIG_CHARTER_COST_ARENA_3v3
Definition: IWorld.h:397
@ GUILD_CHARTER
Definition: PetitionMgr.h:31
@ ARENA_TEAM_CHARTER_2v2
Definition: PetitionMgr.h:32
@ ARENA_TEAM_CHARTER_5v5
Definition: PetitionMgr.h:34
@ ARENA_TEAM_CHARTER_3v3
Definition: PetitionMgr.h:33
@ UNIT_NPC_FLAG_PETITIONER
Definition: UnitDefines.h:312
@ ITEM_FIELD_ENCHANTMENT_1_1
Definition: UpdateFields.h:43
@ CHAR_INS_PETITION
Definition: CharacterDatabase.h:381
@ ARENA_TEAM_CHARTER_2v2_TYPE
Definition: WorldSession.h:223
@ ARENA_TEAM_CHARTER_3v3_TYPE
Definition: WorldSession.h:224
@ ARENA_TEAM_CHARTER_5v5_TYPE
Definition: WorldSession.h:225
uint32 BuyCount
Definition: ItemTemplate.h:629
bool IsTabardDesigner() const
Definition: Unit.h:727
static bool IsValidCharterName(std::string_view name)
Definition: ObjectMgr.cpp:8413
ObjectGuid petitionGuid
Definition: PetitionMgr.h:41

References _player, ARENA_TEAM_CHARTER_2v2, ARENA_TEAM_CHARTER_2v2_TYPE, ARENA_TEAM_CHARTER_3v3, ARENA_TEAM_CHARTER_3v3_TYPE, ARENA_TEAM_CHARTER_5v5, ARENA_TEAM_CHARTER_5v5_TYPE, BUY_ERR_CANT_FIND_ITEM, BUY_ERR_NOT_ENOUGHT_MONEY, ItemTemplate::BuyCount, Player::CanStoreNewItem(), CHAR_INS_PETITION, CharacterDatabase, CONFIG_CHARTER_COST_ARENA_2v2, CONFIG_CHARTER_COST_ARENA_3v3, CONFIG_CHARTER_COST_ARENA_5v5, CONFIG_CHARTER_COST_GUILD, CONFIG_MAX_PLAYER_LEVEL, EQUIP_ERR_OK, ERR_ALREADY_IN_ARENA_TEAM, ERR_ARENA_TEAM_CREATE_S, ERR_ARENA_TEAM_NAME_EXISTS_S, ERR_ARENA_TEAM_NAME_INVALID, ERR_ARENA_TEAM_TARGET_TOO_LOW_S, ERR_GUILD_NAME_EXISTS_S, ERR_GUILD_NAME_INVALID, Player::GetArenaTeamId(), ObjectGuid::GetCounter(), Object::GetGUID(), Player::GetGuildId(), Unit::GetLevel(), WorldObject::GetName(), Player::GetNPCIfCanInteractWith(), GetPlayer(), GUILD_CHARTER, GUILD_CHARTER_TYPE, GUILD_COMMAND_CREATE, Player::HasEnoughMoney(), Unit::IsTabardDesigner(), ObjectMgr::IsValidCharterName(), ITEM_CHANGED, ITEM_FIELD_ENCHANTMENT_1_1, LOG_DEBUG, Player::ModifyMoney(), NULL_BAG, NULL_SLOT, Petition::petitionGuid, ByteBuffer::read_skip(), Unit::RemoveAurasByType(), sArenaTeamMgr, SendArenaTeamCommandResult(), Player::SendBuyError(), Guild::SendCommandResult(), Player::SendEquipError(), Player::SendNewItem(), PreparedStatementBase::SetData(), Item::SetState(), Object::SetUInt32Value(), sGuildMgr, sObjectMgr, SPELL_AURA_FEIGN_DEATH, sPetitionMgr, sScriptMgr, Player::StoreNewItem(), sWorld, ObjectGuid::ToString(), UNIT_NPC_FLAG_PETITIONER, and UNIT_STATE_DIED.

Referenced by OpcodeTable::Initialize().

◆ HandlePetitionDeclineOpcode()

void WorldSession::HandlePetitionDeclineOpcode ( WorldPacket recvData)
530{
531 LOG_DEBUG("network", "Received opcode MSG_PETITION_DECLINE"); // ok
532
533 ObjectGuid petitionguid;
534 ObjectGuid ownerguid;
535 recvData >> petitionguid; // petition guid
536 LOG_DEBUG("network", "Petition {} declined by {}", petitionguid.ToString(), _player->GetGUID().ToString());
537
538 Petition const* petition = sPetitionMgr->GetPetition(petitionguid);
539 if (!petition)
540 return;
541
542 if (Player* owner = ObjectAccessor::FindConnectedPlayer(ownerguid)) // petition owner online
543 {
545 data << _player->GetGUID();
546 owner->GetSession()->SendPacket(&data);
547 }
548}
@ MSG_PETITION_DECLINE
Definition: Opcodes.h:480

References _player, ObjectAccessor::FindConnectedPlayer(), Object::GetGUID(), LOG_DEBUG, MSG_PETITION_DECLINE, sPetitionMgr, and ObjectGuid::ToString().

Referenced by OpcodeTable::Initialize().

◆ HandlePetitionQueryOpcode()

void WorldSession::HandlePetitionQueryOpcode ( WorldPacket recvData)
266{
267 LOG_DEBUG("network", "Received opcode CMSG_PETITION_QUERY"); // ok
268
269 ObjectGuid::LowType guildguid;
270 ObjectGuid petitionguid;
271 recvData >> guildguid; // in Trinity always same as petition low guid
272 recvData >> petitionguid; // petition guid
273 LOG_DEBUG("network", "CMSG_PETITION_QUERY Petition ({}) Guild GUID {}", petitionguid.ToString(), guildguid);
274
275 SendPetitionQueryOpcode(petitionguid);
276}
void SendPetitionQueryOpcode(ObjectGuid petitionguid)
Definition: PetitionsHandler.cpp:278

References LOG_DEBUG, SendPetitionQueryOpcode(), and ObjectGuid::ToString().

Referenced by OpcodeTable::Initialize().

◆ HandlePetitionRenameOpcode()

void WorldSession::HandlePetitionRenameOpcode ( WorldPacket recvData)
326{
327 LOG_DEBUG("network", "Received opcode MSG_PETITION_RENAME"); // ok
328
329 ObjectGuid petitionGuid;
330 std::string newName;
331
332 recvData >> petitionGuid; // guid
333 recvData >> newName; // new name
334
335 Item* item = _player->GetItemByGuid(petitionGuid);
336 if (!item)
337 return;
338
339 Petition const* petition = sPetitionMgr->GetPetition(petitionGuid);
340 if (!petition)
341 {
342 LOG_DEBUG("network", "CMSG_PETITION_QUERY failed for petition ({})", petitionGuid.ToString());
343 return;
344 }
345
346 if (petition->petitionType == GUILD_CHARTER_TYPE)
347 {
348 if (sGuildMgr->GetGuildByName(newName))
349 {
351 return;
352 }
353 if (!ObjectMgr::IsValidCharterName(newName))
354 {
356 return;
357 }
358 }
359 else
360 {
361 if (sArenaTeamMgr->GetArenaTeamByName(newName))
362 {
364 return;
365 }
366 if (!ObjectMgr::IsValidCharterName(newName))
367 {
369 return;
370 }
371 }
372
374
375 stmt->SetData(0, newName);
376 stmt->SetData(1, petitionGuid.GetCounter());
377
378 CharacterDatabase.Execute(stmt);
379
380 // xinef: update petition container
381 const_cast<Petition*>(petition)->petitionName = newName;
382
383 LOG_DEBUG("network", "Petition ({}) renamed to {}", petitionGuid.ToString(), newName);
384 WorldPacket data(MSG_PETITION_RENAME, (8 + newName.size() + 1));
385 data << petitionGuid;
386 data << newName;
387 SendPacket(&data);
388}
@ CHAR_UPD_PETITION_NAME
Definition: CharacterDatabase.h:278
@ MSG_PETITION_RENAME
Definition: Opcodes.h:735

References _player, CHAR_UPD_PETITION_NAME, CharacterDatabase, ERR_ARENA_TEAM_CREATE_S, ERR_ARENA_TEAM_NAME_EXISTS_S, ERR_ARENA_TEAM_NAME_INVALID, ERR_GUILD_NAME_EXISTS_S, ERR_GUILD_NAME_INVALID, ObjectGuid::GetCounter(), Player::GetItemByGuid(), GUILD_CHARTER_TYPE, GUILD_COMMAND_CREATE, ObjectMgr::IsValidCharterName(), LOG_DEBUG, MSG_PETITION_RENAME, Petition::petitionType, sArenaTeamMgr, SendArenaTeamCommandResult(), Guild::SendCommandResult(), SendPacket(), PreparedStatementBase::SetData(), sGuildMgr, sPetitionMgr, and ObjectGuid::ToString().

Referenced by OpcodeTable::Initialize().

◆ HandlePetitionShowListOpcode()

void WorldSession::HandlePetitionShowListOpcode ( WorldPacket recvPacket)
815{
816 LOG_DEBUG("network", "Received CMSG_PETITION_SHOWLIST");
817
818 ObjectGuid guid;
819 recvData >> guid;
820
822}
void SendPetitionShowList(ObjectGuid guid)
Definition: PetitionsHandler.cpp:824

References LOG_DEBUG, and SendPetitionShowList().

Referenced by OpcodeTable::Initialize().

◆ HandlePetitionShowSignOpcode()

void WorldSession::HandlePetitionShowSignOpcode ( WorldPacket recvData)
227{
228 LOG_DEBUG("network", "Received opcode CMSG_PETITION_SHOW_SIGNATURES");
229
230 ObjectGuid petitionguid;
231 recvData >> petitionguid; // petition guid
232
233 // solve (possible) some strange compile problems with explicit use petition low guid at some GCC versions (wrong code optimization in compiler?)
234 Petition const* petition = sPetitionMgr->GetPetition(petitionguid);
235 if (!petition)
236 return;
237
238 uint32 type = petition->petitionType;
239
240 // if guild petition and has guild => error, return;
241 if (type == GUILD_CHARTER_TYPE && _player->GetGuildId())
242 return;
243
244 Signatures const* signatures = sPetitionMgr->GetSignature(petitionguid);
245 uint8 signs = signatures ? signatures->signatureMap.size() : 0;
246
247 LOG_DEBUG("network", "CMSG_PETITION_SHOW_SIGNATURES petition {}", petitionguid.ToString());
248
249 WorldPacket data(SMSG_PETITION_SHOW_SIGNATURES, (8 + 8 + 4 + 1 + signs * 12));
250 data << petitionguid; // petition guid
251 data << _player->GetGUID(); // owner guid
252 data << uint32(petitionguid.GetCounter()); // guild guid
253 data << uint8(signs); // sign's count
254
255 if (signs)
256 for (SignatureMap::const_iterator itr = signatures->signatureMap.begin(); itr != signatures->signatureMap.end(); ++itr)
257 {
258 data << itr->first; // Player GUID
259 data << uint32(0); // there 0 ...
260 }
261
262 SendPacket(&data);
263}

References _player, ObjectGuid::GetCounter(), Object::GetGUID(), Player::GetGuildId(), GUILD_CHARTER_TYPE, LOG_DEBUG, Petition::petitionType, SendPacket(), Signatures::signatureMap, SMSG_PETITION_SHOW_SIGNATURES, sPetitionMgr, and ObjectGuid::ToString().

Referenced by OpcodeTable::Initialize().

◆ HandlePetitionSignOpcode()

void WorldSession::HandlePetitionSignOpcode ( WorldPacket recvData)
391{
392 LOG_DEBUG("network", "Received opcode CMSG_PETITION_SIGN"); // ok
393
394 ObjectGuid petitionGuid;
395 uint8 unk;
396 recvData >> petitionGuid; // petition guid
397 recvData >> unk;
398
399 Petition const* petition = sPetitionMgr->GetPetition(petitionGuid);
400 if (!petition)
401 {
402 LOG_ERROR("network.opcode", "Petition {} is not found for player {} (Name: {})", petitionGuid.ToString(), GetPlayer()->GetGUID().ToString(), GetPlayer()->GetName());
403 return;
404 }
405
406 uint8 type = petition->petitionType;
407
408 ObjectGuid playerGuid = _player->GetGUID();
409 if (petition->ownerGuid == playerGuid)
410 return;
411
412 Signatures const* signatures = sPetitionMgr->GetSignature(petitionGuid);
413 if (!signatures)
414 return;
415
416 if (type != GUILD_CHARTER_TYPE)
417 {
418 if (!sWorld->getBoolConfig(CONFIG_ALLOW_TWO_SIDE_INTERACTION_ARENA) && GetPlayer()->GetTeamId() != sCharacterCache->GetCharacterTeamByGuid(petition->ownerGuid))
419 {
421 return;
422 }
423
424 if (_player->GetLevel() < sWorld->getIntConfig(CONFIG_MAX_PLAYER_LEVEL))
425 {
427 return;
428 }
429
430 uint8 slot = ArenaTeam::GetSlotByType(type);
431 if (slot >= MAX_ARENA_SLOT)
432 return;
433
434 if (_player->GetArenaTeamId(slot))
435 {
437 return;
438 }
439
441 {
443 return;
444 }
445 }
446 else
447 {
448 if (!sWorld->getBoolConfig(CONFIG_ALLOW_TWO_SIDE_INTERACTION_GUILD) && GetPlayer()->GetTeamId() != sCharacterCache->GetCharacterTeamByGuid(petition->ownerGuid))
449 {
451 return;
452 }
453
454 if (_player->GetGuildId())
455 {
457 return;
458 }
460 {
462 return;
463 }
464 }
465
466 uint32 signs = signatures->signatureMap.size();
467 if (++signs > type) // client signs maximum
468 return;
469
470 // Client doesn't allow to sign petition two times by one character, but not check sign by another character from same account
471 // not allow sign another player from already sign player account
472
473 bool found = false;
474 for (SignatureMap::const_iterator itr = signatures->signatureMap.begin(); itr != signatures->signatureMap.end(); ++itr)
475 if (itr->second == GetAccountId())
476 {
477 found = true;
478 break;
479 }
480
481 if (found)
482 {
483 WorldPacket data(SMSG_PETITION_SIGN_RESULTS, (8 + 8 + 4));
484 data << petitionGuid;
485 data << playerGuid;
487
488 // close at signer side
489 SendPacket(&data);
490
491 // update for owner if online
493 owner->GetSession()->SendPacket(&data);
494 return;
495 }
496
498
499 stmt->SetData(0, petition->ownerGuid.GetCounter());
500 stmt->SetData(1, petitionGuid.GetCounter());
501 stmt->SetData(2, playerGuid.GetCounter());
502 stmt->SetData(3, GetAccountId());
503
504 CharacterDatabase.Execute(stmt);
505
506 // xinef: fill petition store
507 sPetitionMgr->AddSignature(petitionGuid, GetAccountId(), playerGuid);
508
509 LOG_DEBUG("network", "PETITION SIGN: {} by player: {} ({}, Account: {})", petitionGuid.ToString(), _player->GetName(), playerGuid.ToString(), GetAccountId());
510
511 WorldPacket data(SMSG_PETITION_SIGN_RESULTS, (8 + 8 + 4));
512 data << petitionGuid;
513 data << playerGuid;
514 data << uint32(PETITION_SIGN_OK);
515
516 // close at signer side
517 SendPacket(&data);
518
519 // update signs count on charter, required testing...
520 //Item* item = _player->GetItemByGuid(petitionguid));
521 //if (item)
522 // item->SetUInt32Value(ITEM_FIELD_ENCHANTMENT_1_1+1, signs);
523
524 // update for owner if online
526 owner->GetSession()->SendPacket(&data);
527}
@ PETITION_SIGN_ALREADY_SIGNED
Definition: Guild.h:182
@ PETITION_SIGN_OK
Definition: Guild.h:181
@ CHAR_INS_PETITION_SIGNATURE
Definition: CharacterDatabase.h:279
@ SMSG_PETITION_SIGN_RESULTS
Definition: Opcodes.h:479
ObjectGuid ownerGuid
Definition: PetitionMgr.h:42

References _player, CHAR_INS_PETITION_SIGNATURE, CharacterDatabase, CONFIG_ALLOW_TWO_SIDE_INTERACTION_ARENA, CONFIG_ALLOW_TWO_SIDE_INTERACTION_GUILD, CONFIG_MAX_PLAYER_LEVEL, ERR_ALREADY_IN_ARENA_TEAM_S, ERR_ALREADY_IN_GUILD_S, ERR_ALREADY_INVITED_TO_ARENA_TEAM_S, ERR_ALREADY_INVITED_TO_GUILD_S, ERR_ARENA_TEAM_CREATE_S, ERR_ARENA_TEAM_INVITE_SS, ERR_ARENA_TEAM_NOT_ALLIED, ERR_ARENA_TEAM_TARGET_TOO_LOW_S, ERR_GUILD_NOT_ALLIED, ObjectAccessor::FindConnectedPlayer(), GetAccountId(), Player::GetArenaTeamId(), Player::GetArenaTeamIdInvited(), ObjectGuid::GetCounter(), Object::GetGUID(), Player::GetGuildId(), Player::GetGuildIdInvited(), Unit::GetLevel(), WorldObject::GetName(), GetPlayer(), ArenaTeam::GetSlotByType(), GetTeamId(), GUILD_CHARTER_TYPE, GUILD_COMMAND_CREATE, GUILD_COMMAND_INVITE, LOG_DEBUG, LOG_ERROR, MAX_ARENA_SLOT, Petition::ownerGuid, PETITION_SIGN_ALREADY_SIGNED, PETITION_SIGN_OK, Petition::petitionType, sCharacterCache, SendArenaTeamCommandResult(), Guild::SendCommandResult(), SendPacket(), PreparedStatementBase::SetData(), Signatures::signatureMap, SMSG_PETITION_SIGN_RESULTS, sPetitionMgr, sWorld, and ObjectGuid::ToString().

Referenced by OpcodeTable::Initialize().

◆ HandlePetLearnTalent()

void WorldSession::HandlePetLearnTalent ( WorldPacket recvPacket)
1107{
1108 LOG_DEBUG("network", "WORLD: CMSG_PET_LEARN_TALENT");
1109
1110 ObjectGuid guid;
1111 uint32 talent_id, requested_rank;
1112 recvData >> guid >> talent_id >> requested_rank;
1113
1114 _player->LearnPetTalent(guid, talent_id, requested_rank);
1116}

References _player, Player::LearnPetTalent(), LOG_DEBUG, and Player::SendTalentsInfoData().

Referenced by OpcodeTable::Initialize().

◆ HandlePetNameQuery()

void WorldSession::HandlePetNameQuery ( WorldPacket recvData)
595{
596 LOG_DEBUG("network.opcode", "HandlePetNameQuery. CMSG_PET_NAME_QUERY");
597
598 uint32 petnumber;
599 ObjectGuid petguid;
600
601 recvData >> petnumber;
602 recvData >> petguid;
603
604 SendPetNameQuery(petguid, petnumber);
605}
void SendPetNameQuery(ObjectGuid guid, uint32 petnumber)
Definition: PetHandler.cpp:607

References LOG_DEBUG, and SendPetNameQuery().

Referenced by OpcodeTable::Initialize().

◆ HandlePetRename()

void WorldSession::HandlePetRename ( WorldPacket recvData)
819{
820 LOG_DEBUG("network.opcode", "HandlePetRename. CMSG_PET_RENAME");
821
822 ObjectGuid petguid;
823 uint8 isdeclined;
824
825 std::string name;
826 DeclinedName declinedname;
827
828 recvData >> petguid;
829 recvData >> name;
830 recvData >> isdeclined;
831
832 PetStable* petStable = _player->GetPetStable();
833
834 Pet* pet = ObjectAccessor::GetPet(*_player, petguid);
835
836 // check it!
837 if (!pet || !pet->IsPet() || ((Pet*)pet)->getPetType() != HUNTER_PET ||
839 pet->GetOwnerGUID() != _player->GetGUID() || !pet->GetCharmInfo() ||
840 !petStable || !petStable->CurrentPet || petStable->CurrentPet->PetNumber != pet->GetCharmInfo()->GetPetNumber())
841 {
842 return;
843 }
844
846 if (res != PET_NAME_SUCCESS)
847 {
848 SendPetNameInvalid(res, name, nullptr);
849 return;
850 }
851
852 pet->SetName(name);
853
854 Unit* owner = pet->GetOwner();
855 if (owner && (owner->IsPlayer()) && owner->ToPlayer()->GetGroup())
857
859
860 petStable->CurrentPet->Name = name;
861 petStable->CurrentPet->WasRenamed = true;
862
863 if (isdeclined)
864 {
865 for (uint8 i = 0; i < MAX_DECLINED_NAME_CASES; ++i)
866 {
867 recvData >> declinedname.name[i];
868 }
869
870 std::wstring wname;
871 Utf8toWStr(name, wname);
872 if (!ObjectMgr::CheckDeclinedNames(wname, declinedname))
873 {
875 return;
876 }
877 }
878
879 CharacterDatabaseTransaction trans = CharacterDatabase.BeginTransaction();
880 if (isdeclined)
881 {
882 if (sWorld->getBoolConfig(CONFIG_DECLINED_NAMES_USED))
883 {
885 stmt->SetData(0, pet->GetCharmInfo()->GetPetNumber());
886 trans->Append(stmt);
887
888 stmt = CharacterDatabase.GetPreparedStatement(CHAR_ADD_CHAR_PET_DECLINEDNAME);
889 stmt->SetData(0, _player->GetGUID().GetCounter());
890
891 for (uint8 i = 0; i < 5; i++)
892 stmt->SetData(i + 1, declinedname.name[i]);
893
894 trans->Append(stmt);
895 }
896 }
897
899 stmt->SetData(0, name);
900 stmt->SetData(1, _player->GetGUID().GetCounter());
901 stmt->SetData(2, pet->GetCharmInfo()->GetPetNumber());
902 trans->Append(stmt);
903
904 CharacterDatabase.CommitTransaction(trans);
905
906 pet->SetUInt32Value(UNIT_FIELD_PET_NAME_TIMESTAMP, uint32(GameTime::GetGameTime().count())); // cast can't be helped
907}
bool Utf8toWStr(char const *utf8str, std::size_t csize, wchar_t *wstr, std::size_t &wsize)
Definition: Util.cpp:281
#define MAX_DECLINED_NAME_CASES
Definition: Unit.h:528
@ UNIT_CAN_BE_RENAMED
Definition: UnitDefines.h:128
@ UNIT_FIELD_PET_NAME_TIMESTAMP
Definition: UpdateFields.h:133
@ CHAR_ADD_CHAR_PET_DECLINEDNAME
Definition: CharacterDatabase.h:480
@ CHAR_UPD_CHAR_PET_NAME
Definition: CharacterDatabase.h:482
@ CHAR_DEL_CHAR_PET_DECLINEDNAME
Definition: CharacterDatabase.h:479
PetNameInvalidReason
Definition: SharedDefines.h:3656
@ PET_NAME_SUCCESS
Definition: SharedDefines.h:3658
@ PET_NAME_DECLENSION_DOESNT_MATCH_BASE_NAME
Definition: SharedDefines.h:3672
Pet * GetPet(WorldObject const &, ObjectGuid const guid)
Definition: ObjectAccessor.cpp:215
void SetName(std::string const &newname)
Definition: Object.h:459
Optional< PetInfo > CurrentPet
Definition: PetDefines.h:225
void SetGroupUpdateFlag(uint32 flag)
Definition: Player.h:2456
PetStable * GetPetStable()
Definition: Player.h:1202
uint32 GetPetNumber() const
Definition: CharmInfo.h:130
Definition: Unit.h:531
std::string name[MAX_DECLINED_NAME_CASES]
Definition: Unit.h:532
static PetNameInvalidReason CheckPetName(std::string_view name)
Definition: ObjectMgr.cpp:8453
static bool CheckDeclinedNames(std::wstring w_ownname, DeclinedName const &names)
Definition: ObjectMgr.cpp:8747
void SendPetNameInvalid(uint32 error, std::string const &name, DeclinedName *declinedName)
Definition: PetHandler.cpp:1090

References _player, CHAR_ADD_CHAR_PET_DECLINEDNAME, CHAR_DEL_CHAR_PET_DECLINEDNAME, CHAR_UPD_CHAR_PET_NAME, CharacterDatabase, ObjectMgr::CheckDeclinedNames(), ObjectMgr::CheckPetName(), CONFIG_DECLINED_NAMES_USED, PetStable::CurrentPet, Unit::GetCharmInfo(), ObjectGuid::GetCounter(), GameTime::GetGameTime(), Player::GetGroup(), Object::GetGUID(), Pet::GetOwner(), Unit::GetOwnerGUID(), ObjectAccessor::GetPet(), CharmInfo::GetPetNumber(), Player::GetPetStable(), GROUP_UPDATE_FLAG_PET_NAME, Object::HasByteFlag(), HUNTER_PET, Unit::IsPet(), Object::IsPlayer(), LOG_DEBUG, MAX_DECLINED_NAME_CASES, DeclinedName::name, PET_NAME_DECLENSION_DOESNT_MATCH_BASE_NAME, PET_NAME_SUCCESS, Object::RemoveByteFlag(), SendPetNameInvalid(), PreparedStatementBase::SetData(), Player::SetGroupUpdateFlag(), WorldObject::SetName(), Unit::SetUInt32Value(), sWorld, Object::ToPlayer(), UNIT_CAN_BE_RENAMED, UNIT_FIELD_BYTES_2, UNIT_FIELD_PET_NAME_TIMESTAMP, and Utf8toWStr().

Referenced by OpcodeTable::Initialize().

◆ HandlePetSetAction()

void WorldSession::HandlePetSetAction ( WorldPacket recvData)
675{
676 LOG_DEBUG("network.opcode", "HandlePetSetAction. CMSG_PET_SET_ACTION");
677
678 ObjectGuid petguid;
679 uint8 count;
680
681 recvData >> petguid;
682
683 Unit* checkPet = ObjectAccessor::GetUnit(*_player, petguid);
684 if (!checkPet || checkPet != _player->GetFirstControlled())
685 {
686 LOG_ERROR("network.opcode", "HandlePetSetAction: Unknown pet ({}) or pet owner ({})", petguid.ToString(), _player->GetGUID().ToString());
687 return;
688 }
689
690 count = (recvData.size() == 24) ? 2 : 1;
691
692 uint32 position[2];
693 uint32 data[2];
694 bool move_command = false;
695
696 for (uint8 i = 0; i < count; ++i)
697 {
698 recvData >> position[i];
699 recvData >> data[i];
700
701 uint8 act_state = UNIT_ACTION_BUTTON_TYPE(data[i]);
702
703 //ignore invalid position
704 if (position[i] >= MAX_UNIT_ACTION_BAR_INDEX)
705 return;
706
707 // in the normal case, command and reaction buttons can only be moved, not removed
708 // at moving count == 2, at removing count == 1
709 // ignore attempt to remove command|reaction buttons (not possible at normal case)
710 if (act_state == ACT_COMMAND || act_state == ACT_REACTION)
711 {
712 if (count == 1)
713 return;
714
715 move_command = true;
716 }
717 }
718
719 Unit::ControlSet petsSet;
720 if (checkPet->GetEntry() != petguid.GetEntry())
721 petsSet.insert(checkPet);
722 else
723 petsSet = _player->m_Controlled;
724
725 // Xinef: loop all pets with same entry (fixes partial state change for feral spirits)
726 for (Unit::ControlSet::const_iterator itr = petsSet.begin(); itr != petsSet.end(); ++itr)
727 {
728 Unit* pet = *itr;
729 if (checkPet->GetEntry() == petguid.GetEntry() && pet->GetEntry() != petguid.GetEntry())
730 continue;
731
732 CharmInfo* charmInfo = pet->GetCharmInfo();
733 if (!charmInfo)
734 {
735 LOG_ERROR("network.opcode", "WorldSession::HandlePetSetAction: object ({} TypeId: {}) is considered pet-like but doesn't have a charminfo!",
736 pet->GetGUID().ToString(), pet->GetTypeId());
737 continue;
738 }
739
740 // check swap (at command->spell swap client remove spell first in another packet, so check only command move correctness)
741 if (move_command)
742 {
743 uint8 act_state_0 = UNIT_ACTION_BUTTON_TYPE(data[0]);
744 if (act_state_0 == ACT_COMMAND || act_state_0 == ACT_REACTION)
745 {
746 uint32 spell_id_0 = UNIT_ACTION_BUTTON_ACTION(data[0]);
747 UnitActionBarEntry const* actionEntry_1 = charmInfo->GetActionBarEntry(position[1]);
748 if (!actionEntry_1 || spell_id_0 != actionEntry_1->GetAction() ||
749 act_state_0 != actionEntry_1->GetType())
750 continue;
751 }
752
753 uint8 act_state_1 = UNIT_ACTION_BUTTON_TYPE(data[1]);
754 if (act_state_1 == ACT_COMMAND || act_state_1 == ACT_REACTION)
755 {
756 uint32 spell_id_1 = UNIT_ACTION_BUTTON_ACTION(data[1]);
757 UnitActionBarEntry const* actionEntry_0 = charmInfo->GetActionBarEntry(position[0]);
758 if (!actionEntry_0 || spell_id_1 != actionEntry_0->GetAction() ||
759 act_state_1 != actionEntry_0->GetType())
760 continue;
761 }
762 }
763
764 for (uint8 i = 0; i < count; ++i)
765 {
766 uint32 spell_id = UNIT_ACTION_BUTTON_ACTION(data[i]);
767 uint8 act_state = UNIT_ACTION_BUTTON_TYPE(data[i]);
768
769 //if it's act for spell (en/disable/cast) and there is a spell given (0 = remove spell) which pet doesn't know, don't add
770 if (!((act_state == ACT_ENABLED || act_state == ACT_DISABLED || act_state == ACT_PASSIVE) && spell_id && !pet->HasSpell(spell_id)))
771 {
772 if (SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(spell_id))
773 {
774 //sign for autocast
775 if (act_state == ACT_ENABLED)
776 {
777 if (pet->IsCreature() && pet->IsPet())
778 {
779 ((Pet*)pet)->ToggleAutocast(spellInfo, true);
780 }
781 else
782 {
783 for (auto iterator = GetPlayer()->m_Controlled.begin(); iterator != GetPlayer()->m_Controlled.end(); ++iterator)
784 {
785 if ((*iterator)->GetEntry() == pet->GetEntry())
786 {
787 (*iterator)->GetCharmInfo()->ToggleCreatureAutocast(spellInfo, true);
788 }
789 }
790 }
791 }
792 //sign for no/turn off autocast
793 else if (act_state == ACT_DISABLED)
794 {
795 if (pet->IsCreature() && pet->IsPet())
796 {
797 ((Pet*)pet)->ToggleAutocast(spellInfo, false);
798 }
799 else
800 {
801 for (auto iterator = GetPlayer()->m_Controlled.begin(); iterator != GetPlayer()->m_Controlled.end(); ++iterator)
802 {
803 if ((*iterator)->GetEntry() == pet->GetEntry())
804 {
805 (*iterator)->GetCharmInfo()->ToggleCreatureAutocast(spellInfo, false);
806 }
807 }
808 }
809 }
810 }
811
812 charmInfo->SetActionBar(position[i], spell_id, ActiveStates(act_state));
813 }
814 }
815 }
816}
#define MAX_UNIT_ACTION_BAR_INDEX
Definition: CharmInfo.h:28
ActiveStates
Definition: CharmInfo.h:59
TypeID GetTypeId() const
Definition: Object.h:124
uint32 GetEntry() const
Definition: ObjectGuid.h:144
Definition: CharmInfo.h:93
ActiveStates GetType() const
Definition: CharmInfo.h:99
uint32 GetAction() const
Definition: CharmInfo.h:100
void SetActionBar(uint8 index, uint32 spellOrAction, ActiveStates type)
Definition: CharmInfo.h:148
UnitActionBarEntry const * GetActionBarEntry(uint8 index) const
Definition: CharmInfo.h:152
std::set< Unit * > ControlSet
Definition: Unit.h:633
Unit * GetFirstControlled() const
Definition: Unit.cpp:11039

References _player, ACT_COMMAND, ACT_DISABLED, ACT_ENABLED, ACT_PASSIVE, ACT_REACTION, UnitActionBarEntry::GetAction(), CharmInfo::GetActionBarEntry(), Unit::GetCharmInfo(), Object::GetEntry(), ObjectGuid::GetEntry(), Unit::GetFirstControlled(), Object::GetGUID(), GetPlayer(), UnitActionBarEntry::GetType(), Object::GetTypeId(), ObjectAccessor::GetUnit(), Unit::HasSpell(), Object::IsCreature(), Unit::IsPet(), LOG_DEBUG, LOG_ERROR, Unit::m_Controlled, MAX_UNIT_ACTION_BAR_INDEX, CharmInfo::SetActionBar(), ByteBuffer::size(), sSpellMgr, ObjectGuid::ToString(), UNIT_ACTION_BUTTON_ACTION, and UNIT_ACTION_BUTTON_TYPE.

Referenced by OpcodeTable::Initialize().

◆ HandlePetSpellAutocastOpcode()

void WorldSession::HandlePetSpellAutocastOpcode ( WorldPackets::Pet::PetSpellAutocast packet)
934{
936 if (!checkPet)
937 {
938 LOG_ERROR("entities.pet", "WorldSession::HandlePetSpellAutocastOpcode: Pet {} not found.", packet.PetGUID.ToString());
939 return;
940 }
941
942 SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(packet.SpellID);
943 if (!spellInfo)
944 {
945 LOG_ERROR("spells.pet", "WorldSession::HandlePetSpellAutocastOpcode: Unknown spell id {} used by {}.", packet.SpellID, packet.PetGUID.ToString());
946 return;
947 }
948
949 if (checkPet != _player->GetGuardianPet() && checkPet != _player->GetCharm())
950 {
951 LOG_ERROR("entities.pet", "WorldSession::HandlePetSpellAutocastOpcode: {} isn't pet of player {} ({}).",
952 packet.PetGUID.ToString(), GetPlayer()->GetName(), GetPlayer()->GetGUID().ToString());
953 return;
954 }
955
956 Unit::ControlSet petsSet;
957 if (checkPet->GetEntry() != packet.PetGUID.GetEntry())
958 petsSet.insert(checkPet);
959 else
960 petsSet = _player->m_Controlled;
961
962 // Xinef: loop all pets with same entry (fixes partial state change for feral spirits)
963 for (Unit* pet : petsSet)
964 {
965 if (checkPet->GetEntry() == packet.PetGUID.GetEntry() && pet->GetEntry() != packet.PetGUID.GetEntry())
966 continue;
967
968 // do not add not learned spells/ passive spells
969 if (!pet->HasSpell(packet.SpellID) || !spellInfo->IsAutocastable())
970 continue;
971
972 CharmInfo* charmInfo = pet->GetCharmInfo();
973 if (!charmInfo)
974 {
975 LOG_ERROR("network.opcode", "WorldSession::HandlePetSpellAutocastOpcode: object ({} TypeId: {}) is considered pet-like but doesn't have a charminfo!",
976 pet->GetGUID().ToString(), pet->GetTypeId());
977 continue;
978 }
979
980 if (Pet* summon = pet->ToPet())
981 summon->ToggleAutocast(spellInfo, packet.AutocastEnabled);
982 else
983 charmInfo->ToggleCreatureAutocast(spellInfo, packet.AutocastEnabled);
984
985 charmInfo->SetSpellAutocast(spellInfo, packet.AutocastEnabled);
986 }
987}
void SetSpellAutocast(SpellInfo const *spellInfo, bool state)
Definition: CharmInfo.cpp:299
void ToggleCreatureAutocast(SpellInfo const *spellInfo, bool apply)
Definition: CharmInfo.cpp:238
bool AutocastEnabled
Definition: PetPackets.h:67
uint32 SpellID
Definition: PetPackets.h:66
ObjectGuid PetGUID
Definition: PetPackets.h:65
bool IsAutocastable() const
Definition: SpellInfo.cpp:1102

References _player, WorldPackets::Pet::PetSpellAutocast::AutocastEnabled, Unit::GetCharm(), ObjectAccessor::GetCreatureOrPetOrVehicle(), Object::GetEntry(), ObjectGuid::GetEntry(), Unit::GetGuardianPet(), GetPlayer(), SpellInfo::IsAutocastable(), LOG_ERROR, Unit::m_Controlled, WorldPackets::Pet::PetSpellAutocast::PetGUID, CharmInfo::SetSpellAutocast(), WorldPackets::Pet::PetSpellAutocast::SpellID, sSpellMgr, CharmInfo::ToggleCreatureAutocast(), Unit::ToPet(), and ObjectGuid::ToString().

Referenced by OpcodeTable::Initialize().

◆ HandlePetStopAttack()

void WorldSession::HandlePetStopAttack ( WorldPackets::Pet::PetStopAttack packet)
128{
130
131 if (!pet)
132 {
133 LOG_ERROR("network.opcode", "HandlePetStopAttack: Pet {} does not exist", packet.PetGUID.ToString());
134 return;
135 }
136
137 if (pet != GetPlayer()->GetPet() && pet != GetPlayer()->GetCharm())
138 {
139 LOG_ERROR("network.opcode", "HandlePetStopAttack: Pet {} isn't a pet or charmed creature of player {}", packet.PetGUID.ToString(), GetPlayer()->GetName());
140 return;
141 }
142
143 if (!pet->IsAlive())
144 return;
145
146 pet->AttackStop();
147 pet->ClearInPetCombat();
148}
ObjectGuid PetGUID
Definition: PetPackets.h:55

References _player, Unit::AttackStop(), Unit::ClearInPetCombat(), ObjectAccessor::GetCreatureOrPetOrVehicle(), GetPlayer(), Unit::IsAlive(), LOG_ERROR, WorldPackets::Pet::PetStopAttack::PetGUID, and ObjectGuid::ToString().

Referenced by OpcodeTable::Initialize().

◆ HandlePlayedTime()

void WorldSession::HandlePlayedTime ( WorldPackets::Character::PlayedTimeClient packet)
1012{
1014 playedTime.TotalTime = _player->GetTotalPlayedTime();
1015 playedTime.LevelTime = _player->GetLevelPlayedTime();
1016 playedTime.TriggerScriptEvent = packet.TriggerScriptEvent; // 0-1 - will not show in chat frame
1017 SendPacket(playedTime.Write());
1018}
uint32 GetLevelPlayedTime()
Definition: Player.h:1187
bool TriggerScriptEvent
Definition: CharacterPackets.h:105
Definition: CharacterPackets.h:109
WorldPacket const * Write() override
Definition: CharacterPackets.cpp:42
uint32 LevelTime
Definition: CharacterPackets.h:116
bool TriggerScriptEvent
Definition: CharacterPackets.h:117
uint32 TotalTime
Definition: CharacterPackets.h:115

References _player, Player::GetLevelPlayedTime(), Player::GetTotalPlayedTime(), WorldPackets::Character::PlayedTime::LevelTime, SendPacket(), WorldPackets::Character::PlayedTime::TotalTime, WorldPackets::Character::PlayedTimeClient::TriggerScriptEvent, WorldPackets::Character::PlayedTime::TriggerScriptEvent, and WorldPackets::Character::PlayedTime::Write().

Referenced by OpcodeTable::Initialize().

◆ HandlePlayerLoginFromDB()

void WorldSession::HandlePlayerLoginFromDB ( LoginQueryHolder const &  holder)
794{
795 ObjectGuid playerGuid = holder.GetGuid();
796
797 Player* pCurrChar = new Player(this);
798 // for send server info and strings (config)
799 ChatHandler chH = ChatHandler(pCurrChar->GetSession());
800
801 // "GetAccountId() == db stored account id" checked in LoadFromDB (prevent login not own character using cheating tools)
802 if (!pCurrChar->LoadFromDB(playerGuid, holder))
803 {
804 SetPlayer(nullptr);
805 KickPlayer("WorldSession::HandlePlayerLogin Player::LoadFromDB failed"); // disconnect client, player no set to session and it will not deleted or saved at kick
806 delete pCurrChar; // delete it manually
807 m_playerLoading = false;
808 return;
809 }
810
811 pCurrChar->GetMotionMaster()->Initialize();
812 pCurrChar->SendDungeonDifficulty(false);
813
815 data << pCurrChar->GetMapId();
816 data << pCurrChar->GetPositionX();
817 data << pCurrChar->GetPositionY();
818 data << pCurrChar->GetPositionZ();
819 data << pCurrChar->GetOrientation();
820 SendPacket(&data);
821
822 // load player specific part before send times
825
826 data.Initialize(SMSG_FEATURE_SYSTEM_STATUS, 2); // added in 2.2.0
827 data << uint8(2); // 2 - COMPLAINT_ENABLED_WITH_AUTO_IGNORE
828 data << uint8(0); // enable(1)/disable(0) voice chat interface in client
829 SendPacket(&data);
830
831 // Send MOTD
832 {
833 SendPacket(sMotdMgr->GetMotdPacket());
834
835 // send server info
836 if (sWorld->getIntConfig(CONFIG_ENABLE_SINFO_LOGIN) == 1)
838 }
839
840 if (uint32 guildId = sCharacterCache->GetCharacterGuildIdByGuid(pCurrChar->GetGUID()))
841 {
842 Guild* guild = sGuildMgr->GetGuildById(guildId);
843 Guild::Member const* member = guild ? guild->GetMember(pCurrChar->GetGUID()) : nullptr;
844 if (member)
845 {
846 pCurrChar->SetInGuild(guildId);
847 pCurrChar->SetRank(member->GetRankId());
848 guild->SendLoginInfo(this);
849 }
850 else
851 {
852 LOG_ERROR("network.opcode", "Player {} ({}) marked as member of not existing guild (id: {}), removing guild membership for player.",
853 pCurrChar->GetName(), pCurrChar->GetGUID().ToString(), guildId);
854 pCurrChar->SetInGuild(0);
855 pCurrChar->SetRank(0);
856 }
857 }
858 else
859 {
860 pCurrChar->SetInGuild(0);
861 pCurrChar->SetRank(0);
862 }
863
864 data.Initialize(SMSG_LEARNED_DANCE_MOVES, 4 + 4);
865 data << uint32(0);
866 data << uint32(0);
867 SendPacket(&data);
868
870
871 //Show cinematic at the first time that player login
872 if (!pCurrChar->getCinematic())
873 {
874 pCurrChar->setCinematic(1);
875
876 if (ChrClassesEntry const* cEntry = sChrClassesStore.LookupEntry(pCurrChar->getClass()))
877 {
878 if (cEntry->CinematicSequence)
879 pCurrChar->SendCinematicStart(cEntry->CinematicSequence);
880 else if (ChrRacesEntry const* rEntry = sChrRacesStore.LookupEntry(pCurrChar->getRace()))
881 pCurrChar->SendCinematicStart(rEntry->CinematicSequence);
882
883 // send new char string if not empty
884 if (!sWorld->GetNewCharString().empty())
885 chH.PSendSysMessage("{}", sWorld->GetNewCharString());
886 }
887 }
888
889 // Xinef: moved this from below
890 ObjectAccessor::AddObject(pCurrChar);
891
892 if (!pCurrChar->GetMap()->AddPlayerToMap(pCurrChar) || !pCurrChar->CheckInstanceLoginValid())
893 {
894 AreaTriggerTeleport const* at = sObjectMgr->GetGoBackTrigger(pCurrChar->GetMapId());
895 if (at)
896 pCurrChar->TeleportTo(at->target_mapId, at->target_X, at->target_Y, at->target_Z, pCurrChar->GetOrientation());
897 else
898 pCurrChar->TeleportTo(pCurrChar->m_homebindMapId, pCurrChar->m_homebindX, pCurrChar->m_homebindY, pCurrChar->m_homebindZ, pCurrChar->GetOrientation());
899
900 // Probably a hackfix, but currently the best workaround to prevent character names showing as Unknown after teleport out from instances at login.
901 pCurrChar->GetSession()->SendNameQueryOpcode(pCurrChar->GetGUID());
902 }
903
905
907 stmt->SetData(0, pCurrChar->GetGUID().GetCounter());
908 CharacterDatabase.Execute(stmt);
909
911 loginStmt->SetData(0, realm.Id.Realm);
912 loginStmt->SetData(1, GetAccountId());
913 LoginDatabase.Execute(loginStmt);
914
915 pCurrChar->SetInGameTime(GameTime::GetGameTimeMS().count());
916
917 // announce group about member online (must be after add to player list to receive announce to self)
918 if (Group* group = pCurrChar->GetGroup())
919 {
920 group->SendUpdate();
921 group->ResetMaxEnchantingLevel();
922 }
923
924 // pussywizard: send instance welcome message as when entering the instance through a portal
925 if (MapDifficulty const* mapDiff = GetMapDifficultyData(pCurrChar->GetMap()->GetId(), pCurrChar->GetMap()->GetDifficulty()))
926 if (mapDiff->resetTime)
927 if (time_t timeReset = sInstanceSaveMgr->GetResetTimeFor(pCurrChar->GetMap()->GetId(), pCurrChar->GetMap()->GetDifficulty()))
928 {
929 uint32 timeleft = uint32(timeReset - GameTime::GetGameTime().count());
930 pCurrChar->SendInstanceResetWarning(pCurrChar->GetMap()->GetId(), pCurrChar->GetMap()->GetDifficulty(), timeleft, true);
931 }
932
933 // pussywizard: ensure that we end up on map with our loaded transport:
934 if (Transport* t = pCurrChar->GetTransport())
935 if (!t->IsInMap(pCurrChar))
936 {
937 t->RemovePassenger(pCurrChar);
938 pCurrChar->m_transport = nullptr;
939 pCurrChar->m_movementInfo.transport.Reset();
941 }
942
943 // friend status
944 sSocialMgr->SendFriendStatus(pCurrChar, FRIEND_ONLINE, pCurrChar->GetGUID(), true);
945
946 // Place character in world (and load zone) before some object loading
947 pCurrChar->LoadCorpse(holder.GetPreparedResult(PLAYER_LOGIN_QUERY_LOAD_CORPSE_LOCATION));
948
949 // setting Ghost+speed if dead
950 if (pCurrChar->m_deathState != DeathState::Alive)
951 {
952 // not blizz like, we must correctly save and load player instead...
953 if (pCurrChar->getRace() == RACE_NIGHTELF)
954 pCurrChar->CastSpell(pCurrChar, 20584, true, 0); // auras SPELL_AURA_INCREASE_SPEED(+speed in wisp form), SPELL_AURA_INCREASE_SWIM_SPEED(+swim speed in wisp form), SPELL_AURA_TRANSFORM (to wisp form)
955
956 pCurrChar->CastSpell(pCurrChar, 8326, true, 0); // auras SPELL_AURA_GHOST, SPELL_AURA_INCREASE_SPEED(why?), SPELL_AURA_INCREASE_SWIM_SPEED(why?)
957 pCurrChar->SetMovement(MOVE_WATER_WALK);
958 }
959
960 // Set FFA PvP for non GM in non-rest mode
961 if (sWorld->IsFFAPvPRealm() && !pCurrChar->IsGameMaster() && !pCurrChar->HasPlayerFlag(PLAYER_FLAGS_RESTING))
963 {
964 sScriptMgr->OnFfaPvpStateUpdate(pCurrChar,true);
966 }
967
969 {
970 pCurrChar->SetContestedPvP(nullptr, false);
971 }
972
973 // Apply at_login requests
975 {
976 pCurrChar->resetSpells();
978 }
979
981 {
982 pCurrChar->resetTalents(true);
983 pCurrChar->SendTalentsInfoData(false); // original talents send already in to SendInitialPacketsBeforeAddToMap, resend reset state
985 }
986
988 {
989 // If we process the check while players are loading they won't be notified of the changes.
990 pCurrChar->m_Events.AddEventAtOffset([pCurrChar]
991 {
993 pCurrChar->CheckAllAchievementCriteria();
994 }, 1s);
995 }
996
997 bool firstLogin = pCurrChar->HasAtLoginFlag(AT_LOGIN_FIRST);
998 if (firstLogin)
999 {
1000 PlayerInfo const* info = sObjectMgr->GetPlayerInfo(pCurrChar->getRace(), pCurrChar->getClass());
1001 for (uint32 spellId : info->castSpells)
1002 {
1003 pCurrChar->CastSpell(pCurrChar, spellId, true);
1004 }
1005
1006 // start with every map explored
1007 if (sWorld->getBoolConfig(CONFIG_START_ALL_EXPLORED))
1008 {
1009 for (uint8 i = 0; i < PLAYER_EXPLORED_ZONES_SIZE; i++)
1010 {
1011 pCurrChar->SetFlag(PLAYER_EXPLORED_ZONES_1 + i, 0xFFFFFFFF);
1012 }
1013 }
1014
1015 // Reputations if "StartAllReputation" is enabled, -- TODO: Fix this in a better way
1016 if (sWorld->getBoolConfig(CONFIG_START_ALL_REP))
1017 {
1018 ReputationMgr& repMgr = pCurrChar->GetReputationMgr();
1019
1020 auto SendFullReputation = [&repMgr](std::initializer_list<uint32> factionsList)
1021 {
1022 for (auto const& itr : factionsList)
1023 {
1024 repMgr.SetOneFactionReputation(sFactionStore.LookupEntry(itr), 42999.f, false);
1025 }
1026 };
1027
1028 SendFullReputation({ 942, 935, 936, 1011, 970, 967, 989, 932, 934, 1038, 1077, 1106, 1104, 1090, 1098, 1156, 1073, 1105, 1119, 1091 });
1029
1030 switch (pCurrChar->GetFaction())
1031 {
1032 case ALLIANCE:
1033 SendFullReputation({ 72, 47, 69, 930, 730, 978, 54, 946, 1037, 1068, 1126, 1094, 1050 });
1034 break;
1035 case HORDE:
1036 SendFullReputation({ 76, 68, 81, 911, 729, 941, 530, 947, 1052, 1067, 1124, 1064, 1085 });
1037 break;
1038 default:
1039 break;
1040 }
1041
1042 repMgr.SendStates();
1043 }
1044 }
1045
1046 // show time before shutdown if shutdown planned.
1047 if (sWorld->IsShuttingDown())
1048 sWorld->ShutdownMsg(true, pCurrChar);
1049
1050 if (sWorld->getBoolConfig(CONFIG_ALL_TAXI_PATHS))
1051 pCurrChar->SetTaxiCheater(true);
1052
1053 if (pCurrChar->IsGameMaster())
1055
1056 std::string IP_str = GetRemoteAddress();
1057 LOG_INFO("entities.player", "Account: {} (IP: {}) Login Character:[{}] ({}) Level: {}",
1058 GetAccountId(), IP_str, pCurrChar->GetName(), pCurrChar->GetGUID().ToString(), pCurrChar->GetLevel());
1059
1060 if (!pCurrChar->IsStandState() && !pCurrChar->HasUnitState(UNIT_STATE_STUNNED))
1062
1063 m_playerLoading = false;
1064
1065 // Handle Login-Achievements (should be handled after loading)
1067
1068 // Xinef: fix vendors falling of player vehicle, due to isBeingLoaded checks
1069 if (pCurrChar->IsInWorld())
1070 {
1071 if (pCurrChar->GetMountBlockId() && !pCurrChar->HasAuraType(SPELL_AURA_MOUNTED))
1072 {
1073 pCurrChar->CastSpell(pCurrChar, pCurrChar->GetMountBlockId(), true);
1074 pCurrChar->SetMountBlockId(0);
1075
1076 // Xinef: refresh this in case mount aura changes anything (eg no fly zone)
1077 pCurrChar->UpdateAreaDependentAuras(pCurrChar->GetAreaId());
1078 pCurrChar->UpdateZoneDependentAuras(pCurrChar->GetZoneId());
1079 }
1080 }
1081
1082 // pussywizard: pvp mode
1084 if (pCurrChar->HasPlayerFlag(PLAYER_FLAGS_IN_PVP))
1085 pCurrChar->UpdatePvP(true, true);
1086
1087 // pussywizard: on login it's not possible to go back to arena as a spectator, HandleMoveWorldportAckOpcode is not sent, so call it here
1088 pCurrChar->SetIsSpectator(false);
1089
1090 // xinef: do this after everything is loaded
1091 pCurrChar->ContinueTaxiFlight();
1092
1093 // reset for all pets before pet loading
1096
1097 // Load pet if any (if player not alive and in taxi flight or another then pet will remember as temporary unsummoned)
1098 pCurrChar->LoadPet();
1099
1100 if (pCurrChar->GetSession()->GetRecruiterId() != 0 || pCurrChar->GetSession()->IsARecruiter())
1101 {
1102 bool isReferrer = pCurrChar->GetSession()->IsARecruiter();
1103
1104 for (auto const& [accID, session] : sWorld->GetAllSessions())
1105 {
1106 if (!session->GetRecruiterId() && !session->IsARecruiter())
1107 continue;
1108
1109 if ((isReferrer && pCurrChar->GetSession()->GetAccountId() == session->GetRecruiterId()) || (!isReferrer && pCurrChar->GetSession()->GetRecruiterId() == session->GetAccountId()))
1110 {
1111 Player* rf = session->GetPlayer();
1112 if (rf)
1113 {
1114 pCurrChar->SendUpdateToPlayer(rf);
1115 rf->SendUpdateToPlayer(pCurrChar);
1116 }
1117 }
1118 }
1119 }
1120
1121 sScriptMgr->OnPlayerLogin(pCurrChar);
1122
1123 if (pCurrChar->HasAtLoginFlag(AT_LOGIN_FIRST))
1124 {
1126 sScriptMgr->OnFirstLogin(pCurrChar);
1127 }
1128
1129 METRIC_EVENT("player_events", "Login", pCurrChar->GetName());
1130}
#define METRIC_EVENT(category, title, description)
Definition: Metric.h:185
#define sMotdMgr
Definition: MotdMgr.h:44
@ CONFIG_ENABLE_SINFO_LOGIN
Definition: IWorld.h:337
@ CONFIG_ALL_TAXI_PATHS
Definition: IWorld.h:83
@ CONFIG_START_ALL_REP
Definition: IWorld.h:127
@ CONFIG_START_ALL_EXPLORED
Definition: IWorld.h:126
@ LANG_RESET_SPELLS
Definition: Language.h:254
@ LANG_RESET_TALENTS
Definition: Language.h:255
@ LANG_GM_ON
Definition: Language.h:373
@ PLAYER_EXPLORED_ZONES_1
Definition: UpdateFields.h:357
@ FRIEND_ONLINE
Definition: SocialMgr.h:68
@ PLAYER_FLAGS_CONTESTED_PVP
Definition: Player.h:482
@ PLAYER_FLAGS_PVP_TIMER
Definition: Player.h:492
@ MOVE_WATER_WALK
Definition: Player.h:458
@ AT_LOGIN_RESET_TALENTS
Definition: Player.h:602
@ AT_LOGIN_RESET_SPELLS
Definition: Player.h:601
@ AT_LOGIN_RESET_PET_TALENTS
Definition: Player.h:604
#define PLAYER_EXPLORED_ZONES_SIZE
Definition: Player.h:72
@ PLAYER_LOGIN_QUERY_LOAD_ACCOUNT_DATA
Definition: Player.h:884
@ PLAYER_LOGIN_QUERY_LOAD_CORPSE_LOCATION
Definition: Player.h:894
@ LOGIN_UPD_ACCOUNT_ONLINE
Definition: LoginDatabase.h:76
@ CHAR_UPD_CHAR_ONLINE
Definition: CharacterDatabase.h:302
@ ALLIANCE
Definition: SharedDefines.h:768
@ HORDE
Definition: SharedDefines.h:767
@ ACHIEVEMENT_CRITERIA_TYPE_ON_LOGIN
Definition: DBCEnums.h:184
#define PER_CHARACTER_CACHE_MASK
Definition: WorldSession.h:179
@ SMSG_LEARNED_DANCE_MOVES
Definition: Opcodes.h:1139
@ SMSG_LOGIN_VERIFY_WORLD
Definition: Opcodes.h:596
@ SMSG_FEATURE_SYSTEM_STATUS
Definition: Opcodes.h:999
AC_COMMON_API char const * GetFullVersion()
Definition: GitRevision.cpp:82
void AddObject(T *object)
Definition: ObjectAccessor.h:89
void AddEventAtOffset(BasicEvent *event, Milliseconds offset)
Definition: EventProcessor.h:107
void SetByteFlag(uint16 index, uint8 offset, uint8 newFlag)
Definition: Object.cpp:911
static void resetTalentsForAllPetsOf(Player *owner, Pet *online_pet=nullptr)
Definition: Pet.cpp:2138
Definition: Player.h:335
PlayerCreateInfoSpells castSpells
Definition: Player.h:349
void RemoveAtLoginFlag(AtLoginFlags flags, bool persist=false)
Definition: Player.cpp:14639
void RemovePlayerFlag(PlayerFlags flags)
Definition: Player.h:1110
uint32 GetMountBlockId()
Definition: Player.h:2586
void ContinueTaxiFlight()
Definition: Player.cpp:10441
void SendDungeonDifficulty(bool IsInGroup)
Definition: PlayerMisc.cpp:167
void UpdateAreaDependentAuras(uint32 area_id)
Definition: PlayerUpdates.cpp:1817
void SetMountBlockId(uint32 mount)
Definition: Player.h:2587
bool resetTalents(bool noResetCost=false)
Definition: Player.cpp:3684
void LoadCorpse(PreparedQueryResult result)
Definition: PlayerStorage.cpp:5816
void SendCinematicStart(uint32 CinematicSequenceId) const
Definition: Player.cpp:5697
void LoadPet()
Definition: PlayerStorage.cpp:6217
uint8 getCinematic() const
Definition: Player.h:1813
void SetRank(uint8 rankId)
Definition: Player.h:1880
bool LoadFromDB(ObjectGuid guid, CharacterDatabaseQueryHolder const &holder)
Definition: PlayerStorage.cpp:4920
void UpdateZoneDependentAuras(uint32 zone_id)
Definition: PlayerUpdates.cpp:1803
void SetMovement(PlayerMovementType pType)
Definition: Player.cpp:4380
void SetTaxiCheater(bool on)
Definition: Player.h:1163
void SetInGameTime(uint32 time)
Definition: Player.h:1545
void CheckAllAchievementCriteria()
Definition: Player.cpp:13903
void setCinematic(uint8 cine)
Definition: Player.h:1817
bool CheckInstanceLoginValid()
Definition: PlayerStorage.cpp:6953
void resetSpells()
Definition: Player.cpp:11818
void SetContestedPvP(Player *attackedPlayer=nullptr, bool lookForNearContestedGuards=true)
Definition: Unit.cpp:17213
DeathState m_deathState
Definition: Unit.h:1871
bool IsStandState() const
Definition: Unit.cpp:16685
void SendLoginInfo(WorldSession *session)
Definition: Guild.cpp:1878
const Member * GetMember(ObjectGuid guid) const
Definition: Guild.h:384
Definition: Guild.h:299
uint8 GetRankId() const
Definition: Guild.h:333
virtual bool AddPlayerToMap(Player *)
Definition: Map.cpp:504
void Initialize()
Definition: MotionMaster.cpp:73
Definition: ReputationMgr.h:58
bool SetOneFactionReputation(FactionEntry const *factionEntry, float standing, bool incremental, Optional< ReputationRank > repMaxCap={ })
Public for chat command needs.
Definition: ReputationMgr.cpp:378
void SendStates()
Definition: ReputationMgr.cpp:246
void SetPlayer(Player *player)
Definition: WorldSession.cpp:1261
void LoadAccountData(PreparedQueryResult result, uint32 mask)
Definition: WorldSession.cpp:845
bool IsARecruiter() const
Definition: WorldSession.h:527
void SendAccountDataTimes(uint32 mask)
Definition: WorldSession.cpp:905

References _player, ACHIEVEMENT_CRITERIA_TYPE_ON_LOGIN, EventProcessor::AddEventAtOffset(), ObjectAccessor::AddObject(), Map::AddPlayerToMap(), ALLIANCE, AT_LOGIN_CHECK_ACHIEVS, AT_LOGIN_FIRST, AT_LOGIN_RESET_PET_TALENTS, AT_LOGIN_RESET_SPELLS, AT_LOGIN_RESET_TALENTS, Unit::CastSpell(), PlayerInfo::castSpells, CHAR_UPD_CHAR_ONLINE, CharacterDatabase, Player::CheckAllAchievementCriteria(), Player::CheckInstanceLoginValid(), CONFIG_ALL_TAXI_PATHS, CONFIG_ENABLE_SINFO_LOGIN, CONFIG_START_ALL_EXPLORED, CONFIG_START_ALL_REP, Player::ContinueTaxiFlight(), FRIEND_ONLINE, GetAccountId(), WorldObject::GetAreaId(), Player::getCinematic(), Unit::getClass(), ObjectGuid::GetCounter(), Map::GetDifficulty(), Unit::GetFaction(), GitRevision::GetFullVersion(), GameTime::GetGameTime(), GameTime::GetGameTimeMS(), Player::GetGroup(), LoginQueryHolder::GetGuid(), Object::GetGUID(), Map::GetId(), Unit::GetLevel(), WorldObject::GetMap(), GetMapDifficultyData(), WorldLocation::GetMapId(), Guild::GetMember(), Unit::GetMotionMaster(), Player::GetMountBlockId(), WorldObject::GetName(), Position::GetOrientation(), Position::GetPositionX(), Position::GetPositionY(), Position::GetPositionZ(), SQLQueryHolderBase::GetPreparedResult(), Unit::getRace(), Guild::Member::GetRankId(), GetRecruiterId(), GetRemoteAddress(), Player::GetReputationMgr(), Player::GetSession(), WorldObject::GetTransport(), WorldObject::GetZoneId(), Player::HasAtLoginFlag(), Unit::HasAuraType(), Object::HasByteFlag(), Player::HasPlayerFlag(), Unit::HasUnitState(), HORDE, Realm::Id, MotionMaster::Initialize(), WorldPacket::Initialize(), IsARecruiter(), Player::IsGameMaster(), Object::IsInWorld(), Unit::IsStandState(), KickPlayer(), LANG_GM_ON, LANG_RESET_SPELLS, LANG_RESET_TALENTS, LoadAccountData(), Player::LoadCorpse(), Player::LoadFromDB(), Player::LoadPet(), LOG_ERROR, LOG_INFO, LOGIN_UPD_ACCOUNT_ONLINE, LoginDatabase, Unit::m_deathState, Unit::m_Events, Player::m_homebindMapId, Player::m_homebindX, Player::m_homebindY, Player::m_homebindZ, WorldObject::m_movementInfo, m_playerLoading, WorldObject::m_transport, METRIC_EVENT, MOVE_WATER_WALK, MOVEMENTFLAG_ONTRANSPORT, PER_CHARACTER_CACHE_MASK, PLAYER_EXPLORED_ZONES_1, PLAYER_EXPLORED_ZONES_SIZE, PLAYER_FLAGS_CONTESTED_PVP, PLAYER_FLAGS_IN_PVP, PLAYER_FLAGS_PVP_TIMER, PLAYER_FLAGS_RESTING, PLAYER_LOGIN_QUERY_LOAD_ACCOUNT_DATA, PLAYER_LOGIN_QUERY_LOAD_CORPSE_LOCATION, ChatHandler::PSendSysMessage(), RACE_NIGHTELF, realm, RealmHandle::Realm, Player::RemoveAtLoginFlag(), MovementInfo::RemoveMovementFlag(), Player::RemovePlayerFlag(), MovementInfo::TransportInfo::Reset(), Player::resetSpells(), Player::resetTalents(), Pet::resetTalentsForAllPetsOf(), sCharacterCache, sChrClassesStore, sChrRacesStore, SendAccountDataTimes(), Player::SendCinematicStart(), Player::SendDungeonDifficulty(), Player::SendInitialPacketsAfterAddToMap(), Player::SendInitialPacketsBeforeAddToMap(), Player::SendInstanceResetWarning(), Guild::SendLoginInfo(), SendNameQueryOpcode(), ChatHandler::SendNotification(), SendPacket(), ReputationMgr::SendStates(), Player::SendTalentsInfoData(), Object::SendUpdateToPlayer(), Object::SetByteFlag(), Player::setCinematic(), Unit::SetContestedPvP(), PreparedStatementBase::SetData(), Object::SetFlag(), Player::SetInGameTime(), Player::SetInGuild(), Player::SetIsSpectator(), Player::SetMountBlockId(), Player::SetMovement(), ReputationMgr::SetOneFactionReputation(), SetPlayer(), Player::SetRank(), Unit::SetStandState(), Player::SetTaxiCheater(), sFactionStore, sGuildMgr, sInstanceSaveMgr, sMotdMgr, SMSG_FEATURE_SYSTEM_STATUS, SMSG_LEARNED_DANCE_MOVES, SMSG_LOGIN_VERIFY_WORLD, sObjectMgr, SPELL_AURA_MOUNTED, sScriptMgr, sSocialMgr, sWorld, AreaTriggerTeleport::target_mapId, AreaTriggerTeleport::target_X, AreaTriggerTeleport::target_Y, AreaTriggerTeleport::target_Z, Player::TeleportTo(), ObjectGuid::ToString(), MovementInfo::transport, UNIT_BYTE2_FLAG_FFA_PVP, UNIT_FIELD_BYTES_2, UNIT_STAND_STATE_STAND, UNIT_STATE_STUNNED, Player::UpdateAchievementCriteria(), Player::UpdateAreaDependentAuras(), Player::UpdatePvP(), and Player::UpdateZoneDependentAuras().

Referenced by HandlePlayerLoginOpcode().

◆ HandlePlayerLoginOpcode()

void WorldSession::HandlePlayerLoginOpcode ( WorldPacket recvPacket)
668{
669 m_playerLoading = true;
670 ObjectGuid playerGuid;
671 recvData >> playerGuid;
672
673 if (PlayerLoading() || GetPlayer() != nullptr || !playerGuid.IsPlayer())
674 {
675 // limit player interaction with the world
676 if (!sWorld->getBoolConfig(CONFIG_REALM_LOGIN_ENABLED))
677 {
679 // see LoginFailureReason enum for more reasons
680 data << uint8(LoginFailureReason::NoWorld);
681 SendPacket(&data);
682 return;
683 }
684 }
685
686 if (!playerGuid.IsPlayer() || !IsLegitCharacterForAccount(playerGuid))
687 {
688 LOG_ERROR("network", "Account ({}) can't login with that character ({}).", GetAccountId(), playerGuid.ToString());
689 KickPlayer("Account can't login with this character");
690 return;
691 }
692
693 auto SendCharLogin = [&](ResponseCodes result)
694 {
696 data << uint8(result);
697 SendPacket(&data);
698 };
699
700 // pussywizard:
701 if (WorldSession* sess = sWorld->FindOfflineSessionForCharacterGUID(playerGuid.GetCounter()))
702 if (sess->GetAccountId() != GetAccountId())
703 {
704 SendCharLogin(CHAR_LOGIN_DUPLICATE_CHARACTER);
705 return;
706 }
707 // pussywizard:
708 if (WorldSession* sess = sWorld->FindOfflineSession(GetAccountId()))
709 {
710 Player* p = sess->GetPlayer();
711 if (!p || sess->IsKicked())
712 {
713 SendCharLogin(CHAR_LOGIN_DUPLICATE_CHARACTER);
714 return;
715 }
716
717 if (p->GetGUID() != playerGuid)
718 sess->KickPlayer("No return, go to normal loading"); // no return, go to normal loading
719 else
720 {
721 // pussywizard: players stay ingame no matter what (prevent abuse), but allow to turn it off to stop crashing
722 if (!sWorld->getBoolConfig(CONFIG_ENABLE_LOGIN_AFTER_DC))
723 {
724 SendCharLogin(CHAR_LOGIN_DUPLICATE_CHARACTER);
725 return;
726 }
727
728 uint8 limitA = 10, limitB = 10, limitC = 10; // pussywizard: this somehow froze (probably, ahh crash logs ...), and while (far) have never frozen in LogoutPlayer o_O maybe it's the combination of while(far); while(near);
729 while (sess->GetPlayer() && (sess->GetPlayer()->IsBeingTeleportedFar() || (sess->GetPlayer()->IsInWorld() && sess->GetPlayer()->IsBeingTeleportedNear())))
730 {
731 if (limitA == 0 || --limitA == 0)
732 {
733 LOG_INFO("misc", "HandlePlayerLoginOpcode A");
734 break;
735 }
736 while (sess->GetPlayer() && sess->GetPlayer()->IsBeingTeleportedFar())
737 {
738 if (limitB == 0 || --limitB == 0)
739 {
740 LOG_INFO("misc", "HandlePlayerLoginOpcode B");
741 break;
742 }
743 sess->HandleMoveWorldportAck();
744 }
745 while (sess->GetPlayer() && sess->GetPlayer()->IsInWorld() && sess->GetPlayer()->IsBeingTeleportedNear())
746 {
747 if (limitC == 0 || --limitC == 0)
748 {
749 LOG_INFO("misc", "HandlePlayerLoginOpcode C");
750 break;
751 }
752
753 Player* plMover = sess->GetPlayer()->m_mover->ToPlayer();
754 if (!plMover)
755 break;
756
758 pkt << plMover->GetPackGUID();
759 pkt << uint32(0); // flags
760 pkt << uint32(0); // time
761 sess->HandleMoveTeleportAck(pkt);
762 }
763 }
764 if (!p->FindMap() || !p->IsInWorld() || sess->IsKicked())
765 {
766 SendCharLogin(CHAR_LOGIN_DUPLICATE_CHARACTER);
767 return;
768 }
769
770 sess->SetPlayer(nullptr);
771 SetPlayer(p);
772 p->SetSession(this);
773 delete p->PlayerTalkClass;
776 return;
777 }
778 }
779
780 std::shared_ptr<LoginQueryHolder> holder = std::make_shared<LoginQueryHolder>(GetAccountId(), playerGuid);
781 if (!holder->Initialize())
782 {
783 m_playerLoading = false;
784 return;
785 }
786
787 AddQueryHolderCallback(CharacterDatabase.DelayQueryHolder(holder)).AfterComplete([this](SQLQueryHolderBase const& holder)
788 {
789 HandlePlayerLoginFromDB(static_cast<LoginQueryHolder const&>(holder));
790 });
791}
@ CONFIG_ENABLE_LOGIN_AFTER_DC
Definition: IWorld.h:143
@ CONFIG_REALM_LOGIN_ENABLED
Definition: IWorld.h:170
@ CHAR_LOGIN_DUPLICATE_CHARACTER
Definition: SharedDefines.h:3410
@ SMSG_CHARACTER_LOGIN_FAILED
Definition: Opcodes.h:95
@ MSG_MOVE_TELEPORT_ACK
Definition: Opcodes.h:229
Definition: QueryHolder.h:25
void AfterComplete(std::function< void(SQLQueryHolderBase const &)> callback) &
Definition: QueryHolder.h:77
Definition: GossipDef.h:258
void SetSession(WorldSession *sess)
Definition: Player.h:1981
Definition: CharacterHandler.cpp:62
Player session in the World.
Definition: WorldSession.h:330
bool PlayerLoading() const
Definition: WorldSession.h:337
void HandlePlayerLoginToCharInWorld(Player *pCurrChar)
Definition: CharacterHandler.cpp:1132
SQLQueryHolderCallback & AddQueryHolderCallback(SQLQueryHolderCallback &&callback)
Definition: WorldSession.cpp:1282
void HandlePlayerLoginFromDB(LoginQueryHolder const &holder)
Definition: CharacterHandler.cpp:793

References AddQueryHolderCallback(), SQLQueryHolderCallback::AfterComplete(), CHAR_LOGIN_DUPLICATE_CHARACTER, CharacterDatabase, CONFIG_ENABLE_LOGIN_AFTER_DC, CONFIG_REALM_LOGIN_ENABLED, WorldObject::FindMap(), GetAccountId(), ObjectGuid::GetCounter(), Object::GetGUID(), Object::GetPackGUID(), GetPlayer(), Player::GetSession(), HandlePlayerLoginFromDB(), HandlePlayerLoginToCharInWorld(), Object::IsInWorld(), IsLegitCharacterForAccount(), ObjectGuid::IsPlayer(), KickPlayer(), LOG_ERROR, LOG_INFO, Player::m_mover, m_playerLoading, MSG_MOVE_TELEPORT_ACK, PlayerLoading(), Player::PlayerTalkClass, SendPacket(), SetPlayer(), Player::SetSession(), SMSG_CHARACTER_LOGIN_FAILED, sWorld, Object::ToPlayer(), and ObjectGuid::ToString().

Referenced by OpcodeTable::Initialize().

◆ HandlePlayerLoginToCharInWorld()

void WorldSession::HandlePlayerLoginToCharInWorld ( Player pCurrChar)
1133{
1134 ChatHandler chH = ChatHandler(this);
1135 m_playerLoading = true;
1136
1137 pCurrChar->SendDungeonDifficulty(false);
1138
1140 data << pCurrChar->GetMapId();
1141 data << pCurrChar->GetPositionX();
1142 data << pCurrChar->GetPositionY();
1143 data << pCurrChar->GetPositionZ();
1144 data << pCurrChar->GetOrientation();
1145 SendPacket(&data);
1146
1148
1149 data.Initialize(SMSG_FEATURE_SYSTEM_STATUS, 2); // added in 2.2.0
1150 data << uint8(2); // unknown value
1151 data << uint8(0); // enable(1)/disable(0) voice chat interface in client
1152 SendPacket(&data);
1153
1154 // Send MOTD
1155 {
1156 SendPacket(sMotdMgr->GetMotdPacket());
1157
1158 // send server info
1159 if (sWorld->getIntConfig(CONFIG_ENABLE_SINFO_LOGIN) == 1)
1161
1162 LOG_DEBUG("network.opcode", "WORLD: Sent server info");
1163 }
1164
1165 data.Initialize(SMSG_LEARNED_DANCE_MOVES, 4 + 4);
1166 data << uint32(0);
1167 data << uint32(0);
1168 SendPacket(&data);
1169
1170 // Xinef: fix possible problem with flag UNIT_FLAG_STUNNED added during logout
1171 if (!pCurrChar->HasUnitState(UNIT_STATE_STUNNED))
1173
1175
1176 // necessary actions from AddPlayerToMap:
1177 pCurrChar->GetMap()->SendInitTransports(pCurrChar);
1178 pCurrChar->GetMap()->SendInitSelf(pCurrChar);
1179 pCurrChar->GetMap()->SendZoneDynamicInfo(pCurrChar);
1180 pCurrChar->m_clientGUIDs.clear();
1181 pCurrChar->UpdateObjectVisibility(false);
1182
1183 pCurrChar->CleanupChannels();
1185 uint32 currZone, currArea;
1186 pCurrChar->GetZoneAndAreaId(currZone, currArea);
1187 pCurrChar->SendInitWorldStates(currZone, currArea);
1188 pCurrChar->SetInGameTime(GameTime::GetGameTimeMS().count());
1189
1190 // Xinef: we need to resend all spell mods
1191 for (uint16 Opcode = SMSG_SET_FLAT_SPELL_MODIFIER; Opcode <= SMSG_SET_PCT_SPELL_MODIFIER; ++Opcode) // PCT = FLAT+1
1192 {
1194 for (uint32 opType = SPELLMOD_DAMAGE; opType < MAX_SPELLMOD; ++opType)
1195 {
1196 int32 i = 0;
1197 flag96 _mask = 0;
1198 SpellModList const& spellMods = pCurrChar->GetSpellModList(opType);
1199 if (spellMods.empty())
1200 continue;
1201
1202 for (int32 eff = 0; eff < 96; ++eff)
1203 {
1204 if (eff != 0 && eff % 32 == 0)
1205 _mask[i++] = 0;
1206
1207 _mask[i] = uint32(1) << (eff - (32 * i));
1208 int32 val = 0;
1209 for (auto const& spellMod : spellMods)
1210 if (spellMod->type == modType && spellMod->mask & _mask)
1211 val += spellMod->value;
1212
1213 if (val == 0)
1214 continue;
1215
1216 WorldPacket data(Opcode, (1 + 1 + 4));
1217 data << uint8(eff);
1218 data << uint8(opType);
1219 data << int32(val);
1220 SendPacket(&data);
1221 }
1222 }
1223 }
1224
1225 if (Group* group = pCurrChar->GetGroup())
1226 group->SendUpdate();
1227
1228 // pussywizard: send instance welcome message as when entering the instance through a portal
1229 if (MapDifficulty const* mapDiff = GetMapDifficultyData(pCurrChar->GetMap()->GetId(), pCurrChar->GetMap()->GetDifficulty()))
1230 if (mapDiff->resetTime)
1231 if (time_t timeReset = sInstanceSaveMgr->GetResetTimeFor(pCurrChar->GetMap()->GetId(), pCurrChar->GetMap()->GetDifficulty()))
1232 {
1233 uint32 timeleft = uint32(timeReset - GameTime::GetGameTime().count());
1234 GetPlayer()->SendInstanceResetWarning(pCurrChar->GetMap()->GetId(), pCurrChar->GetMap()->GetDifficulty(), timeleft, true);
1235 }
1236
1237 // this shouldn't do anything, becaues offline can't be on taxi, but just in case
1238 pCurrChar->ContinueTaxiFlight();
1239
1240 // send pet data, action bar, talents, etc.
1241 pCurrChar->PetSpellInitialize();
1242 pCurrChar->SendTalentsInfoData(true);
1243
1244 // show time before shutdown if shutdown planned.
1245 if (sWorld->IsShuttingDown())
1246 sWorld->ShutdownMsg(true, pCurrChar);
1247
1248 if (pCurrChar->IsGameMaster())
1250
1251 m_playerLoading = false;
1252}
std::list< SpellModifier * > SpellModList
Definition: Player.h:194
@ SPELLMOD_FLAT
Definition: Player.h:93
@ SPELLMOD_PCT
Definition: Player.h:94
@ SPELLMOD_DAMAGE
Definition: SpellDefines.h:76
#define MAX_SPELLMOD
Definition: SpellDefines.h:109
@ SMSG_SET_FLAT_SPELL_MODIFIER
Definition: Opcodes.h:644
@ SMSG_SET_PCT_SPELL_MODIFIER
Definition: Opcodes.h:645
Definition: Util.h:451
void CleanupChannels()
Definition: Player.cpp:4989
SpellModList const & GetSpellModList(uint32 type) const
Definition: Player.h:2594
void PetSpellInitialize()
Definition: Player.cpp:9468
GuidUnorderedSet m_clientGUIDs
Definition: Player.h:2363
void SendInitWorldStates(uint32 zone, uint32 area)
Definition: Player.cpp:8186
void UpdateObjectVisibility(bool forced=true, bool fromUpdate=false) override
Definition: PlayerUpdates.cpp:1567
void SendZoneDynamicInfo(Player *player)
Definition: Map.cpp:3718
void SendInitSelf(Player *player)
Definition: Map.cpp:2529
void SendInitTransports(Player *player)
Definition: Map.cpp:2564

References Player::CleanupChannels(), CONFIG_ENABLE_SINFO_LOGIN, Player::ContinueTaxiFlight(), Map::GetDifficulty(), GitRevision::GetFullVersion(), GameTime::GetGameTime(), GameTime::GetGameTimeMS(), Player::GetGroup(), Map::GetId(), WorldObject::GetMap(), GetMapDifficultyData(), WorldLocation::GetMapId(), Position::GetOrientation(), GetPlayer(), Position::GetPositionX(), Position::GetPositionY(), Position::GetPositionZ(), Player::GetSession(), Player::GetSpellModList(), WorldObject::GetZoneAndAreaId(), Unit::HasUnitState(), WorldPacket::Initialize(), Player::IsGameMaster(), LANG_GM_ON, LOG_DEBUG, Player::m_clientGUIDs, m_playerLoading, MAX_SPELLMOD, PER_CHARACTER_CACHE_MASK, Player::PetSpellInitialize(), ChatHandler::PSendSysMessage(), Unit::RemoveUnitFlag(), SendAccountDataTimes(), Player::SendDungeonDifficulty(), Player::SendInitialPacketsAfterAddToMap(), Player::SendInitialPacketsBeforeAddToMap(), Map::SendInitSelf(), Map::SendInitTransports(), Player::SendInitWorldStates(), Player::SendInstanceResetWarning(), ChatHandler::SendNotification(), SendPacket(), Player::SendTalentsInfoData(), Map::SendZoneDynamicInfo(), Player::SetInGameTime(), sInstanceSaveMgr, sMotdMgr, SMSG_FEATURE_SYSTEM_STATUS, SMSG_LEARNED_DANCE_MOVES, SMSG_LOGIN_VERIFY_WORLD, SMSG_SET_FLAT_SPELL_MODIFIER, SMSG_SET_PCT_SPELL_MODIFIER, SPELLMOD_DAMAGE, SPELLMOD_FLAT, SPELLMOD_PCT, sWorld, UNIT_FLAG_STUNNED, UNIT_STATE_STUNNED, and Player::UpdateObjectVisibility().

Referenced by HandlePlayerLoginOpcode().

◆ HandlePlayerLoginToCharOutOfWorld()

void WorldSession::HandlePlayerLoginToCharOutOfWorld ( Player pCurrChar)
1255{
1256 ABORT();
1257}
#define ABORT
Definition: Errors.h:76

References ABORT.

◆ HandlePlayerLogoutOpcode()

void WorldSession::HandlePlayerLogoutOpcode ( WorldPackets::Character::PlayerLogout playerLogout)
478{
479}

Referenced by OpcodeTable::Initialize().

◆ HandlePushQuestToParty()

void WorldSession::HandlePushQuestToParty ( WorldPacket recvPacket)
540{
541 uint32 questId;
542 recvPacket >> questId;
543
544 if (!_player->CanShareQuest(questId))
545 return;
546
547 LOG_DEBUG("network", "WORLD: Received CMSG_PUSHQUESTTOPARTY quest = {}", questId);
548
549 if (Quest const* quest = sObjectMgr->GetQuestTemplate(questId))
550 {
551 if (Group* group = _player->GetGroup())
552 {
553 for (GroupReference* itr = group->GetFirstMember(); itr != nullptr; itr = itr->next())
554 {
555 Player* player = itr->GetSource();
556
557 if (!player || player == _player || !player->IsInMap(_player)) // skip self
558 continue;
559
560 if (!player->SatisfyQuestStatus(quest, false))
561 {
563 continue;
564 }
565
566 if (player->GetQuestStatus(questId) == QUEST_STATUS_COMPLETE)
567 {
569 continue;
570 }
571
572 if (!player->CanTakeQuest(quest, false))
573 {
575 continue;
576 }
577
578 if (!player->SatisfyQuestLog(false))
579 {
581 continue;
582 }
583
584 // Check if Quest Share in BG is enabled
586 {
587 // Check if player is in BG
588 if (_player->InBattleground())
589 {
591 continue;
592 }
593 }
594
595 if (player->GetDivider())
596 {
598 continue;
599 }
600
602
603 if (quest->IsAutoAccept() && player->CanAddQuest(quest, true) && player->CanTakeQuest(quest, true))
604 player->AddQuestAndCheckCompletion(quest, _player);
605
606 if (quest->IsAutoComplete() || !quest->GetQuestMethod())
608 else
609 {
610 player->SetDivider(_player->GetGUID());
611 player->PlayerTalkClass->SendQuestGiverQuestDetails(quest, player->GetGUID(), true);
612 }
613 }
614 }
615 }
616}
@ QUEST_STATUS_COMPLETE
Definition: QuestDef.h:101
@ QUEST_PARTY_MSG_FINISH_QUEST
Definition: QuestDef.h:73
@ QUEST_PARTY_MSG_CANT_TAKE_QUEST
Definition: QuestDef.h:67
@ QUEST_PARTY_MSG_BUSY
Definition: QuestDef.h:70
@ QUEST_PARTY_MSG_HAVE_QUEST
Definition: QuestDef.h:72
@ QUEST_PARTY_MSG_SHARING_QUEST
Definition: QuestDef.h:66
@ QUEST_PARTY_MSG_LOG_FULL
Definition: QuestDef.h:71
@ CONFIG_BATTLEGROUND_DISABLE_QUEST_SHARE_IN_BG
Definition: IWorld.h:109
@ LANG_BG_SHARE_QUEST_ERROR
Definition: Language.h:1323
void SendQuestGiverQuestDetails(Quest const *quest, ObjectGuid npcGUID, bool activateAccept) const
Definition: GossipDef.cpp:388
void SendQuestGiverRequestItems(Quest const *quest, ObjectGuid npcGUID, bool canComplete, bool closeOnCancel) const
Definition: GossipDef.cpp:752
bool IsInMap(WorldObject const *obj) const
Definition: Object.cpp:1285
bool CanTakeQuest(Quest const *quest, bool msg)
Definition: PlayerQuest.cpp:251
bool CanAddQuest(Quest const *quest, bool msg)
Definition: PlayerQuest.cpp:264
ObjectGuid GetDivider()
Definition: Player.h:1540
void SendPushToPartyResponse(Player const *player, uint8 msg) const
Definition: PlayerQuest.cpp:2429
bool SatisfyQuestLog(bool msg)
Definition: PlayerQuest.cpp:978
void AddQuestAndCheckCompletion(Quest const *quest, Object *questGiver)
Definition: PlayerQuest.cpp:420
bool CanCompleteRepeatableQuest(Quest const *quest)
Definition: PlayerQuest.cpp:365
bool CanShareQuest(uint32 quest_id) const
Definition: PlayerQuest.cpp:1452
void SetDivider(ObjectGuid guid=ObjectGuid::Empty)
Definition: Player.h:1541
bool SatisfyQuestStatus(Quest const *qInfo, bool msg) const
Definition: PlayerQuest.cpp:1142

References _player, Player::AddQuestAndCheckCompletion(), Player::CanAddQuest(), Player::CanCompleteRepeatableQuest(), Player::CanShareQuest(), Player::CanTakeQuest(), CONFIG_BATTLEGROUND_DISABLE_QUEST_SHARE_IN_BG, Player::GetDivider(), Player::GetGroup(), Object::GetGUID(), Player::GetQuestStatus(), Player::GetSession(), Player::InBattleground(), WorldObject::IsInMap(), LANG_BG_SHARE_QUEST_ERROR, LOG_DEBUG, GroupReference::next(), Player::PlayerTalkClass, QUEST_PARTY_MSG_BUSY, QUEST_PARTY_MSG_CANT_TAKE_QUEST, QUEST_PARTY_MSG_FINISH_QUEST, QUEST_PARTY_MSG_HAVE_QUEST, QUEST_PARTY_MSG_LOG_FULL, QUEST_PARTY_MSG_SHARING_QUEST, QUEST_STATUS_COMPLETE, Player::SatisfyQuestLog(), Player::SatisfyQuestStatus(), ChatHandler::SendNotification(), Player::SendPushToPartyResponse(), PlayerMenu::SendQuestGiverQuestDetails(), PlayerMenu::SendQuestGiverRequestItems(), Player::SetDivider(), sObjectMgr, and sWorld.

Referenced by OpcodeTable::Initialize().

◆ HandlePVPLogDataOpcode()

void WorldSession::HandlePVPLogDataOpcode ( WorldPacket recvData)
348{
349 LOG_DEBUG("network", "WORLD: Recvd MSG_PVP_LOG_DATA Message");
350
352 if (!bg)
353 return;
354
355 // Prevent players from sending BuildPvpLogDataPacket in an arena except for when sent in BattleGround::EndBattleGround.
356 if (bg->isArena())
357 return;
358
359 WorldPacket data;
360 bg->BuildPvPLogDataPacket(data);
361 SendPacket(&data);
362
363 LOG_DEBUG("network", "WORLD: Sent MSG_PVP_LOG_DATA Message");
364}
void BuildPvPLogDataPacket(WorldPacket &data)
Definition: Battleground.cpp:1316

References _player, Battleground::BuildPvPLogDataPacket(), Player::GetBattleground(), Battleground::isArena(), LOG_DEBUG, and SendPacket().

Referenced by OpcodeTable::Initialize().

◆ HandleQueryGuildBankTabText()

void WorldSession::HandleQueryGuildBankTabText ( WorldPackets::Guild::GuildBankTextQuery packet)
389{
390 LOG_DEBUG("guild", "MSG_QUERY_GUILD_BANK_TEXT [{}]: TabId: {}", GetPlayerInfo(), packet.Tab);
391
392 if (Guild* guild = GetPlayer()->GetGuild())
393 guild->SendBankTabText(this, packet.Tab);
394}
uint8 Tab
Definition: GuildPackets.h:563

References GetPlayer(), GetPlayerInfo(), LOG_DEBUG, and WorldPackets::Guild::GuildBankTextQuery::Tab.

Referenced by OpcodeTable::Initialize().

◆ HandleQueryInspectAchievements()

void WorldSession::HandleQueryInspectAchievements ( WorldPacket recvData)
1610{
1611 ObjectGuid guid;
1612 recv_data >> guid.ReadAsPacked();
1613
1614 Player* player = ObjectAccessor::GetPlayer(*_player, guid);
1615 if (!player)
1616 {
1617 return;
1618 }
1619
1620 if (!GetPlayer()->IsWithinDistInMap(player, INSPECT_DISTANCE, false))
1621 {
1622 return;
1623 }
1624
1625 if (GetPlayer()->IsValidAttackTarget(player))
1626 {
1627 return;
1628 }
1629
1631}
void SendRespondInspectAchievements(Player *player) const
Definition: Player.cpp:13913

References _player, GetPlayer(), ObjectAccessor::GetPlayer(), INSPECT_DISTANCE, ObjectGuid::ReadAsPacked(), and Player::SendRespondInspectAchievements().

Referenced by OpcodeTable::Initialize().

◆ HandleQueryNextMailTime()

void WorldSession::HandleQueryNextMailTime ( WorldPacket recvData)
825{
827
828 if (_player->unReadMails > 0)
829 {
830 data << float(0); // float
831 data << uint32(0); // count
832
833 uint32 count = 0;
834 time_t now = GameTime::GetGameTime().count();
835 std::set<uint32> sentSenders;
836 for (Mail const* mail : _player->GetMails())
837 {
838 // must be not checked yet
839 if (mail->checked & MAIL_CHECK_MASK_READ)
840 continue;
841
842 // and already delivered or expired
843 if (now < mail->deliver_time || now > mail->expire_time)
844 continue;
845
846 // only send each mail sender once
847 if (sentSenders.count(mail->sender))
848 continue;
849
850 data << (mail->messageType == MAIL_NORMAL ? ObjectGuid::Create<HighGuid::Player>(mail->sender) : ObjectGuid::Empty); // player guid
851 data << uint32(mail->messageType != MAIL_NORMAL ? mail->sender : 0); // non-player entries
852 data << uint32(mail->messageType);
853 data << uint32(mail->stationery);
854 data << float(mail->deliver_time - now);
855
856 sentSenders.insert(mail->sender);
857 ++count;
858 if (count == 2) // do not display more than 2 mails
859 break;
860 }
861
862 data.put<uint32>(4, count);
863 }
864 else
865 {
866 data << float(-DAY);
867 data << uint32(0);
868 }
869
870 SendPacket(&data);
871}
@ MSG_QUERY_NEXT_MAIL_TIME
Definition: Opcodes.h:674

References _player, DAY, ObjectGuid::Empty, GameTime::GetGameTime(), Player::GetMails(), MAIL_CHECK_MASK_READ, MAIL_NORMAL, MSG_QUERY_NEXT_MAIL_TIME, ByteBuffer::put(), SendPacket(), and Player::unReadMails.

Referenced by OpcodeTable::Initialize().

◆ HandleQueryQuestsCompleted()

void WorldSession::HandleQueryQuestsCompleted ( WorldPacket recvData)
644{
645 std::size_t rew_count = _player->GetRewardedQuestCount();
646
647 WorldPacket data(SMSG_QUERY_QUESTS_COMPLETED_RESPONSE, 4 + 4 * rew_count);
648 data << uint32(rew_count);
649
650 const RewardedQuestSet& rewQuests = _player->getRewardedQuests();
651 for (RewardedQuestSet::const_iterator itr = rewQuests.begin(); itr != rewQuests.end(); ++itr)
652 data << uint32(*itr);
653
654 SendPacket(&data);
655}
std::unordered_set< uint32 > RewardedQuestSet
Definition: Player.h:615
@ SMSG_QUERY_QUESTS_COMPLETED_RESPONSE
Definition: Opcodes.h:1311
std::size_t GetRewardedQuestCount() const
Definition: Player.h:1619
RewardedQuestSet const & getRewardedQuests() const
Definition: Player.h:1615

References _player, Player::GetRewardedQuestCount(), Player::getRewardedQuests(), SendPacket(), and SMSG_QUERY_QUESTS_COMPLETED_RESPONSE.

Referenced by OpcodeTable::Initialize().

◆ HandleQueryTimeOpcode()

void WorldSession::HandleQueryTimeOpcode ( WorldPacket recvPacket)

◆ HandleQuestConfirmAccept()

void WorldSession::HandleQuestConfirmAccept ( WorldPacket recvData)
454{
455 uint32 questId;
456 recvData >> questId;
457
458 LOG_DEBUG("network", "WORLD: Received CMSG_QUEST_CONFIRM_ACCEPT quest = {}", questId);
459
460 if (Quest const* quest = sObjectMgr->GetQuestTemplate(questId))
461 {
462 if (!quest->HasFlag(QUEST_FLAGS_PARTY_ACCEPT))
463 return;
464
466 if (!originalPlayer)
467 return;
468
469 if (!_player->IsInSameRaidWith(originalPlayer) || !_player->IsAtGroupRewardDistance(originalPlayer))
470 return;
471
472 if (!_player->CanTakeQuest(quest, true) || _player->HasPendingBind())
473 return;
474
475 // pussywizard: exploit fix, can't share quests that give items to be sold
476 if (uint32 itemId = quest->GetSrcItemId())
477 if (ItemTemplate const* srcItem = sObjectMgr->GetItemTemplate(itemId))
478 if (srcItem->SellPrice > 0)
479 return;
480
481 if (_player->CanAddQuest(quest, true))
482 _player->AddQuestAndCheckCompletion(quest, nullptr); // nullptr, this prevent DB script from duplicate running
483
485 }
486}
@ QUEST_FLAGS_PARTY_ACCEPT
Definition: QuestDef.h:133
bool IsInSameRaidWith(Player const *p) const
Definition: Player.h:1868
bool IsAtGroupRewardDistance(WorldObject const *pRewardSource) const
Definition: Player.cpp:12764

References _player, Player::AddQuestAndCheckCompletion(), Player::CanAddQuest(), Player::CanTakeQuest(), Player::GetDivider(), ObjectAccessor::GetPlayer(), Player::HasPendingBind(), Player::IsAtGroupRewardDistance(), Player::IsInSameRaidWith(), LOG_DEBUG, QUEST_FLAGS_PARTY_ACCEPT, Player::SetDivider(), and sObjectMgr.

Referenced by OpcodeTable::Initialize().

◆ HandleQuestgiverAcceptQuestOpcode()

void WorldSession::HandleQuestgiverAcceptQuestOpcode ( WorldPacket recvPacket)
115{
116 ObjectGuid guid;
117 uint32 questId;
118 uint32 unk1;
119 recvData >> guid >> questId >> unk1;
120
121 LOG_DEBUG("network", "WORLD: Received CMSG_QUESTGIVER_ACCEPT_QUEST npc {}, quest = {}, unk1 = {}", guid.ToString(), questId, unk1);
122
124
125 // no or incorrect quest giver
126 if (!object || object == _player || (!object->IsPlayer() && !object->hasQuest(questId)) ||
127 (object->IsPlayer() && !object->ToPlayer()->CanShareQuest(questId)))
128 {
131 return;
132 }
133
134 // some kind of WPE protection
136 return;
137
138 if (Quest const* quest = sObjectMgr->GetQuestTemplate(questId))
139 {
140 // pussywizard: exploit fix, can't share quests that give items to be sold
141 if (object->IsPlayer())
142 if (uint32 itemId = quest->GetSrcItemId())
143 if (ItemTemplate const* srcItem = sObjectMgr->GetItemTemplate(itemId))
144 if (srcItem->SellPrice > 0)
145 return;
146
147 // prevent cheating
148 if (!GetPlayer()->CanTakeQuest(quest, true))
149 {
152 return;
153 }
154
155 if (_player->GetDivider())
156 {
158 if (player)
159 {
162 }
163 }
164
165 if (_player->CanAddQuest(quest, true))
166 {
167 _player->AddQuestAndCheckCompletion(quest, object);
168
169 if (quest->HasFlag(QUEST_FLAGS_PARTY_ACCEPT))
170 {
171 if (Group* group = _player->GetGroup())
172 {
173 for (GroupReference* itr = group->GetFirstMember(); itr != nullptr; itr = itr->next())
174 {
175 Player* itrPlayer = itr->GetSource();
176 if (!itrPlayer || itrPlayer == _player || !itrPlayer->IsAtGroupRewardDistance(_player) || itrPlayer->HasPendingBind()) // xinef: check range
177 continue;
178
179 if (itrPlayer->CanTakeQuest(quest, false))
180 {
181 itrPlayer->SetDivider(_player->GetGUID());
182
183 // need confirmation that any gossip window will close
184 itrPlayer->PlayerTalkClass->SendCloseGossip();
185
186 _player->SendQuestConfirmAccept(quest, itrPlayer);
187 }
188 }
189 }
190 }
191
193
194 if (quest->GetSrcSpell() > 0)
195 _player->CastSpell(_player, quest->GetSrcSpell(), true);
196
197 return;
198 }
199 }
200
202}
@ QUEST_PARTY_MSG_ACCEPT_QUEST
Definition: QuestDef.h:68
@ TYPEMASK_ITEM
Definition: ObjectGuid.h:47
@ TYPEMASK_UNIT
Definition: ObjectGuid.h:49
@ TYPEMASK_GAMEOBJECT
Definition: ObjectGuid.h:51
@ TYPEMASK_PLAYER
Definition: ObjectGuid.h:50
Object * GetObjectByTypeMask(WorldObject const &, ObjectGuid const guid, uint32 typemask)
Definition: ObjectAccessor.cpp:141
Definition: Object.h:100
virtual bool hasQuest(uint32) const
Definition: Object.h:186
void SendQuestConfirmAccept(Quest const *quest, Player *pReceiver)
Definition: PlayerQuest.cpp:2407
bool CanInteractWithQuestGiver(Object *questGiver)
Definition: Player.cpp:2057

References _player, Player::AddQuestAndCheckCompletion(), Player::CanAddQuest(), Player::CanInteractWithQuestGiver(), Player::CanShareQuest(), Player::CanTakeQuest(), Unit::CastSpell(), Player::GetDivider(), Player::GetGroup(), Object::GetGUID(), ObjectAccessor::GetObjectByTypeMask(), GetPlayer(), ObjectAccessor::GetPlayer(), Player::HasPendingBind(), Object::hasQuest(), Player::IsAtGroupRewardDistance(), Object::IsPlayer(), LOG_DEBUG, GroupReference::next(), Player::PlayerTalkClass, QUEST_FLAGS_PARTY_ACCEPT, QUEST_PARTY_MSG_ACCEPT_QUEST, PlayerMenu::SendCloseGossip(), Player::SendPushToPartyResponse(), Player::SendQuestConfirmAccept(), Player::SetDivider(), sObjectMgr, Object::ToPlayer(), ObjectGuid::ToString(), TYPEMASK_GAMEOBJECT, TYPEMASK_ITEM, TYPEMASK_PLAYER, and TYPEMASK_UNIT.

Referenced by OpcodeTable::Initialize().

◆ HandleQuestgiverCancel()

void WorldSession::HandleQuestgiverCancel ( WorldPacket recvData)

◆ HandleQuestgiverChooseRewardOpcode()

void WorldSession::HandleQuestgiverChooseRewardOpcode ( WorldPacket recvPacket)
252{
253 uint32 questId, reward;
254 ObjectGuid guid;
255 recvData >> guid >> questId >> reward;
256
257 if (reward >= QUEST_REWARD_CHOICES_COUNT)
258 {
259 LOG_ERROR("network.opcode", "Error in CMSG_QUESTGIVER_CHOOSE_REWARD: player {} ({}) tried to get invalid reward ({}) (probably packet hacking)",
260 _player->GetName(), _player->GetGUID().ToString(), reward);
261 return;
262 }
263
264 LOG_DEBUG("network", "WORLD: Received CMSG_QUESTGIVER_CHOOSE_REWARD npc {}, quest = {}, reward = {}", guid.ToString(), questId, reward);
265
267 if (!object || !object->hasInvolvedQuest(questId))
268 return;
269
270 // some kind of WPE protection
272 return;
273
274 if (Quest const* quest = sObjectMgr->GetQuestTemplate(questId))
275 {
276 if ((!_player->CanSeeStartQuest(quest) && _player->GetQuestStatus(questId) == QUEST_STATUS_NONE) ||
277 (_player->GetQuestStatus(questId) != QUEST_STATUS_COMPLETE && !quest->IsAutoComplete() && quest->GetQuestMethod()))
278 {
279 LOG_ERROR("network.opcode", "HACK ALERT: Player {} ({}) is trying to complete quest (id: {}) but he has no right to do it!",
280 _player->GetName(), _player->GetGUID().ToString(), questId);
281 return;
282 }
283 if (_player->CanRewardQuest(quest, reward, true))
284 {
285 _player->RewardQuest(quest, reward, object);
286
287 // Special dialog status update (client does not query this)
288 if (!quest->GetQuestMethod())
289 {
291 }
292
293 switch (object->GetTypeId())
294 {
295 case TYPEID_UNIT:
296 {
297 Creature* questgiver = object->ToCreature();
298 if (!sScriptMgr->OnQuestReward(_player, questgiver, quest, reward))
299 {
300 // Send next quest
301 if (Quest const* nextQuest = _player->GetNextQuest(guid, quest))
302 {
303 if (_player->CanTakeQuest(nextQuest, false))
304 {
305 if (nextQuest->IsAutoAccept())
306 {
307 // QUEST_FLAGS_AUTO_ACCEPT was not used by Blizzard.
308 if (_player->CanAddQuest(nextQuest, false))
309 {
310 _player->AddQuestAndCheckCompletion(nextQuest, object);
311 }
312 else
313 {
314 // Auto accept is set for a custom quest and there is no inventory space
316 break;
317 }
318 }
319 _player->PlayerTalkClass->SendQuestGiverQuestDetails(nextQuest, guid, true);
320 }
321 }
322
323 questgiver->AI()->sQuestReward(_player, quest, reward);
324 }
325 break;
326 }
328 {
329 GameObject* questGiver = object->ToGameObject();
330 if (!sScriptMgr->OnQuestReward(_player, questGiver, quest, reward))
331 {
332 // Send next quest
333 if (Quest const* nextQuest = _player->GetNextQuest(guid, quest))
334 {
335 if (_player->CanAddQuest(nextQuest, false) && _player->CanTakeQuest(nextQuest, false))
336 {
337 if (nextQuest->IsAutoAccept())
338 _player->AddQuestAndCheckCompletion(nextQuest, object);
339 _player->PlayerTalkClass->SendQuestGiverQuestDetails(nextQuest, guid, true);
340 }
341 }
342
343 questGiver->AI()->QuestReward(_player, quest, reward);
344 }
345 break;
346 }
347 default:
348 break;
349 }
350 }
351 else
353 }
354}
@ QUEST_STATUS_NONE
Definition: QuestDef.h:100
#define QUEST_REWARD_CHOICES_COUNT
Definition: QuestDef.h:38
@ TYPEID_GAMEOBJECT
Definition: ObjectGuid.h:37
@ TYPEID_UNIT
Definition: ObjectGuid.h:35
virtual bool QuestReward(Player *, Quest const *, uint32)
Definition: GameObjectAI.h:58
virtual void sQuestReward(Player *, Quest const *, uint32)
Definition: UnitAI.h:419
void SendQuestGiverStatus(uint8 questStatus, ObjectGuid npcGUID) const
Definition: GossipDef.cpp:378
void SendQuestGiverOfferReward(Quest const *quest, ObjectGuid npcGUID, bool enableNext) const
Definition: GossipDef.cpp:647
GameObject * ToGameObject()
Definition: Object.h:210
virtual bool hasInvolvedQuest(uint32) const
Definition: Object.h:187
QuestGiverStatus GetQuestDialogStatus(Object *questGiver)
Definition: PlayerQuest.cpp:1589
bool CanSeeStartQuest(Quest const *quest)
Definition: PlayerQuest.cpp:237
Quest const * GetNextQuest(ObjectGuid guid, Quest const *quest)
Definition: PlayerQuest.cpp:207
void RewardQuest(Quest const *quest, uint32 reward, Object *questGiver, bool announce=true, bool isLFGReward=false)
Definition: PlayerQuest.cpp:658

References _player, Player::AddQuestAndCheckCompletion(), Creature::AI(), GameObject::AI(), Player::CanAddQuest(), Player::CanInteractWithQuestGiver(), Player::CanRewardQuest(), Player::CanSeeStartQuest(), Player::CanTakeQuest(), Object::GetGUID(), WorldObject::GetName(), Player::GetNextQuest(), ObjectAccessor::GetObjectByTypeMask(), Player::GetQuestDialogStatus(), Player::GetQuestStatus(), Object::GetTypeId(), Object::hasInvolvedQuest(), LOG_DEBUG, LOG_ERROR, Player::PlayerTalkClass, QUEST_REWARD_CHOICES_COUNT, QUEST_STATUS_COMPLETE, QUEST_STATUS_NONE, GameObjectAI::QuestReward(), Player::RewardQuest(), PlayerMenu::SendCloseGossip(), PlayerMenu::SendQuestGiverOfferReward(), PlayerMenu::SendQuestGiverQuestDetails(), PlayerMenu::SendQuestGiverStatus(), sObjectMgr, UnitAI::sQuestReward(), sScriptMgr, Object::ToCreature(), Object::ToGameObject(), ObjectGuid::ToString(), TYPEID_GAMEOBJECT, TYPEID_UNIT, TYPEMASK_GAMEOBJECT, and TYPEMASK_UNIT.

Referenced by OpcodeTable::Initialize().

◆ HandleQuestgiverCompleteQuest()

void WorldSession::HandleQuestgiverCompleteQuest ( WorldPacket recvData)
489{
490 uint32 questId;
491 ObjectGuid guid;
492
493 recvData >> guid >> questId;
494
495 LOG_DEBUG("network", "WORLD: Received CMSG_QUESTGIVER_COMPLETE_QUEST npc {}, quest = {}", guid.ToString(), questId);
496
498 if (!object || !object->hasInvolvedQuest(questId))
499 return;
500
501 // some kind of WPE protection
503 return;
504
505 if (Quest const* quest = sObjectMgr->GetQuestTemplate(questId))
506 {
508 {
509 LOG_ERROR("network.opcode", "Possible hacking attempt: Player {} [{}] tried to complete quest [entry: {}] without being in possession of the quest!",
510 _player->GetName(), _player->GetGUID().ToString(), questId);
511 return;
512 }
513
515 if (bg->GetBgTypeID(true) == BATTLEGROUND_AV)
516 bg->ToBattlegroundAV()->HandleQuestComplete(questId, _player);
517
519 {
520 if (quest->IsRepeatable())
522 else
523 _player->PlayerTalkClass->SendQuestGiverRequestItems(quest, guid, _player->CanRewardQuest(quest, false), false);
524 }
525 else
526 {
527 if (quest->GetReqItemsCount()) // some items required
528 _player->PlayerTalkClass->SendQuestGiverRequestItems(quest, guid, _player->CanRewardQuest(quest, false), false);
529 else // no items required
531 }
532 }
533}
@ BATTLEGROUND_AV
Definition: SharedDefines.h:3481

References _player, BATTLEGROUND_AV, Player::CanCompleteRepeatableQuest(), Player::CanInteractWithQuestGiver(), Player::CanRewardQuest(), Player::CanSeeStartQuest(), Player::GetBattleground(), Object::GetGUID(), WorldObject::GetName(), ObjectAccessor::GetObjectByTypeMask(), Player::GetQuestStatus(), Object::hasInvolvedQuest(), LOG_DEBUG, LOG_ERROR, Player::PlayerTalkClass, QUEST_STATUS_COMPLETE, QUEST_STATUS_NONE, PlayerMenu::SendQuestGiverOfferReward(), PlayerMenu::SendQuestGiverRequestItems(), sObjectMgr, ObjectGuid::ToString(), TYPEMASK_GAMEOBJECT, and TYPEMASK_UNIT.

Referenced by OpcodeTable::Initialize().

◆ HandleQuestgiverHelloOpcode()

void WorldSession::HandleQuestgiverHelloOpcode ( WorldPacket recvPacket)
83{
84 ObjectGuid guid;
85 recvData >> guid;
86
87 LOG_DEBUG("network", "WORLD: Received CMSG_QUESTGIVER_HELLO npc {}", guid.ToString());
88
90 if (!creature)
91 {
92 LOG_DEBUG("network", "WORLD: HandleQuestgiverHelloOpcode - Unit ({}) not found or you can't interact with him.", guid.ToString());
93 return;
94 }
95
96 // remove fake death
97 if (GetPlayer()->HasUnitState(UNIT_STATE_DIED))
99
100 // Stop the npc if moving
101 if (uint32 pause = creature->GetMovementTemplate().GetInteractionPauseTimer())
102 creature->PauseMovement(pause);
103 creature->SetHomePosition(creature->GetPosition());
104
105 if (sScriptMgr->OnGossipHello(_player, creature))
106 return;
107
108 _player->PrepareGossipMenu(creature, creature->GetCreatureTemplate()->GossipMenuId, true);
109 _player->SendPreparedGossip(creature);
110
111 creature->AI()->sGossipHello(_player);
112}

References _player, Creature::AI(), Creature::GetCreatureTemplate(), CreatureMovementData::GetInteractionPauseTimer(), Creature::GetMovementTemplate(), Player::GetNPCIfCanInteractWith(), GetPlayer(), Position::GetPosition(), CreatureTemplate::GossipMenuId, LOG_DEBUG, Unit::PauseMovement(), Player::PrepareGossipMenu(), Unit::RemoveAurasByType(), Player::SendPreparedGossip(), Creature::SetHomePosition(), UnitAI::sGossipHello(), SPELL_AURA_FEIGN_DEATH, sScriptMgr, ObjectGuid::ToString(), UNIT_NPC_FLAG_NONE, and UNIT_STATE_DIED.

Referenced by OpcodeTable::Initialize().

◆ HandleQuestgiverQueryQuestOpcode()

void WorldSession::HandleQuestgiverQueryQuestOpcode ( WorldPacket recvPacket)
205{
206 ObjectGuid guid;
207 uint32 questId;
208 uint8 unk1;
209 recvData >> guid >> questId >> unk1;
210 LOG_DEBUG("network", "WORLD: Received CMSG_QUESTGIVER_QUERY_QUEST npc {}, quest = {}, unk1 = {}", guid.ToString(), questId, unk1);
211
212 // Verify that the guid is valid and is a questgiver or involved in the requested quest
214 if (!object || (!object->hasQuest(questId) && !object->hasInvolvedQuest(questId)))
215 {
217 return;
218 }
219
220 if (Quest const* quest = sObjectMgr->GetQuestTemplate(questId))
221 {
222 // not sure here what should happen to quests with QUEST_FLAGS_AUTOCOMPLETE
223 // if this breaks them, add && object->IsItem() to this check
224 // item-started quests never have that flag
225 if (!_player->CanTakeQuest(quest, true))
226 return;
227
228 if (quest->IsAutoAccept() && _player->CanAddQuest(quest, true))
229 _player->AddQuestAndCheckCompletion(quest, object);
230
231 if (quest->IsAutoComplete() || !quest->GetQuestMethod())
232 _player->PlayerTalkClass->SendQuestGiverRequestItems(quest, object->GetGUID(), _player->CanCompleteQuest(quest->GetQuestId()), true);
233 else
235 }
236}
bool CanCompleteQuest(uint32 quest_id, const QuestStatusData *q_savedStatus=nullptr)
Definition: PlayerQuest.cpp:288

References _player, Player::AddQuestAndCheckCompletion(), Player::CanAddQuest(), Player::CanCompleteQuest(), Player::CanTakeQuest(), Object::GetGUID(), ObjectAccessor::GetObjectByTypeMask(), Object::hasInvolvedQuest(), Object::hasQuest(), LOG_DEBUG, Player::PlayerTalkClass, PlayerMenu::SendCloseGossip(), PlayerMenu::SendQuestGiverQuestDetails(), PlayerMenu::SendQuestGiverRequestItems(), sObjectMgr, ObjectGuid::ToString(), TYPEMASK_GAMEOBJECT, TYPEMASK_ITEM, and TYPEMASK_UNIT.

Referenced by OpcodeTable::Initialize().

◆ HandleQuestgiverQuestAutoLaunch()

void WorldSession::HandleQuestgiverQuestAutoLaunch ( WorldPacket recvPacket)
536{
537}

Referenced by OpcodeTable::Initialize().

◆ HandleQuestgiverRequestRewardOpcode()

void WorldSession::HandleQuestgiverRequestRewardOpcode ( WorldPacket recvPacket)
357{
358 uint32 questId;
359 ObjectGuid guid;
360 recvData >> guid >> questId;
361
362 LOG_DEBUG("network", "WORLD: Received CMSG_QUESTGIVER_REQUEST_REWARD npc {}, quest = {}", guid.ToString(), questId);
363
365 if (!object || !object->hasInvolvedQuest(questId))
366 return;
367
368 // some kind of WPE protection
370 return;
371
372 if (_player->CanCompleteQuest(questId))
373 _player->CompleteQuest(questId);
374
376 return;
377
378 if (Quest const* quest = sObjectMgr->GetQuestTemplate(questId))
380}
void CompleteQuest(uint32 quest_id)
Definition: PlayerQuest.cpp:597

References _player, Player::CanCompleteQuest(), Player::CanInteractWithQuestGiver(), Player::CompleteQuest(), ObjectAccessor::GetObjectByTypeMask(), Player::GetQuestStatus(), Object::hasInvolvedQuest(), LOG_DEBUG, Player::PlayerTalkClass, QUEST_STATUS_COMPLETE, PlayerMenu::SendQuestGiverOfferReward(), sObjectMgr, ObjectGuid::ToString(), TYPEMASK_GAMEOBJECT, and TYPEMASK_UNIT.

Referenced by OpcodeTable::Initialize().

◆ HandleQuestgiverStatusMultipleQuery()

void WorldSession::HandleQuestgiverStatusMultipleQuery ( WorldPacket recvPacket)

◆ HandleQuestgiverStatusQueryOpcode()

void WorldSession::HandleQuestgiverStatusQueryOpcode ( WorldPacket recvPacket)
36{
37 ObjectGuid guid;
38 recvData >> guid;
39 uint32 questStatus = DIALOG_STATUS_NONE;
40
42 // Did we already get a gossip menu with that NPC? if so no need to status query
43 if (gossipMenu.GetSenderGUID() == guid)
44 {
45 return;
46 }
47
49 if (!questGiver)
50 {
51 LOG_DEBUG("network.opcode", "Error in CMSG_QUESTGIVER_STATUS_QUERY, called for not found questgiver ({})", guid.ToString());
52 return;
53 }
54
55 switch (questGiver->GetTypeId())
56 {
57 case TYPEID_UNIT:
58 {
59 LOG_DEBUG("network", "WORLD: Received CMSG_QUESTGIVER_STATUS_QUERY for npc {}", guid.ToString());
60 if (!questGiver->ToCreature()->IsHostileTo(_player)) // do not show quest status to enemies
61 questStatus = _player->GetQuestDialogStatus(questGiver);
62 break;
63 }
65 {
66 LOG_DEBUG("network", "WORLD: Received CMSG_QUESTGIVER_STATUS_QUERY for GameObject {}", guid.ToString());
67 if (sWorld->getBoolConfig(CONFIG_OBJECT_QUEST_MARKERS))
68 {
69 questStatus = _player->GetQuestDialogStatus(questGiver);
70 }
71 break;
72 }
73 default:
74 LOG_ERROR("network.opcode", "QuestGiver called for unexpected type {}", questGiver->GetTypeId());
75 break;
76 }
77
78 // inform client about status of quest
80}
@ DIALOG_STATUS_NONE
Definition: QuestDef.h:112
@ CONFIG_OBJECT_QUEST_MARKERS
Definition: IWorld.h:180
Definition: GossipDef.h:162
bool IsHostileTo(Unit const *unit) const
Definition: Unit.cpp:10205

References _player, CONFIG_OBJECT_QUEST_MARKERS, DIALOG_STATUS_NONE, PlayerMenu::GetGossipMenu(), ObjectAccessor::GetObjectByTypeMask(), Player::GetQuestDialogStatus(), GossipMenu::GetSenderGUID(), Object::GetTypeId(), Unit::IsHostileTo(), LOG_DEBUG, LOG_ERROR, Player::PlayerTalkClass, PlayerMenu::SendQuestGiverStatus(), sWorld, Object::ToCreature(), ObjectGuid::ToString(), TYPEID_GAMEOBJECT, TYPEID_UNIT, TYPEMASK_GAMEOBJECT, and TYPEMASK_UNIT.

Referenced by OpcodeTable::Initialize().

◆ HandleQuestLogRemoveQuest()

void WorldSession::HandleQuestLogRemoveQuest ( WorldPacket recvData)
401{
402 uint8 slot;
403 recvData >> slot;
404
405 LOG_DEBUG("network", "WORLD: Received CMSG_QUESTLOG_REMOVE_QUEST slot = {}", slot);
406
407 if (slot < MAX_QUEST_LOG_SIZE)
408 {
409 if (uint32 questId = _player->GetQuestSlotQuestId(slot))
410 {
411 if (!_player->TakeQuestSourceItem(questId, true))
412 return; // can't un-equip some items, reject quest cancel
413
414 if (Quest const* quest = sObjectMgr->GetQuestTemplate(questId))
415 {
416 if (quest->HasSpecialFlag(QUEST_SPECIAL_FLAGS_TIMED))
417 _player->RemoveTimedQuest(questId);
418
419 if (quest->HasFlag(QUEST_FLAGS_FLAGS_PVP))
420 {
423 }
424 }
425
426 _player->TakeQuestSourceItem(questId, true); // remove quest src item from player
427 _player->AbandonQuest(questId); // remove all quest items player received before abandoning quest.
428 _player->RemoveActiveQuest(questId);
430
431 sScriptMgr->OnQuestAbandon(_player, questId);
432
433 LOG_DEBUG("network.opcode", "Player {} abandoned quest {}", _player->GetGUID().ToString(), questId);
434 // check if Quest Tracker is enabled
435 if (sWorld->getBoolConfig(CONFIG_QUEST_ENABLE_QUEST_TRACKER))
436 {
437 // prepare Quest Tracker datas
438 auto stmt = CharacterDatabase.GetPreparedStatement(CHAR_UPD_QUEST_TRACK_ABANDON_TIME);
439 stmt->SetData(0, questId);
440 stmt->SetData(1, _player->GetGUID().GetCounter());
441
442 // add to Quest Tracker
443 CharacterDatabase.Execute(stmt);
444 }
445 }
446
447 _player->SetQuestSlot(slot, 0);
448
450 }
451}
@ QUEST_FLAGS_FLAGS_PVP
Definition: QuestDef.h:145
#define MAX_QUEST_LOG_SIZE
Definition: QuestDef.h:33
@ QUEST_SPECIAL_FLAGS_TIMED
Definition: QuestDef.h:178
@ CONFIG_QUEST_ENABLE_QUEST_TRACKER
Definition: IWorld.h:147
@ CHAR_UPD_QUEST_TRACK_ABANDON_TIME
Definition: CharacterDatabase.h:504
@ ACHIEVEMENT_TIMED_TYPE_QUEST
Definition: DBCEnums.h:111
@ ACHIEVEMENT_CRITERIA_TYPE_QUEST_ABANDONED
Definition: DBCEnums.h:214
bool IsInHostileArea
Definition: Player.h:361
bool HasPvPForcingQuest() const
Definition: PlayerQuest.cpp:2489
void UpdatePvPState()
Definition: PlayerUpdates.cpp:1390
uint32 GetQuestSlotQuestId(uint16 slot) const
Definition: Player.h:1476
void SetQuestSlot(uint16 slot, uint32 quest_id, uint32 timer=0)
Definition: Player.h:1480
bool TakeQuestSourceItem(uint32 questId, bool msg)
Definition: PlayerQuest.cpp:1357
void RemoveActiveQuest(uint32 questId, bool update=true)
Definition: PlayerQuest.cpp:1489
void RemoveTimedQuest(uint32 quest_id)
Definition: Player.h:1548
void RemoveTimedAchievement(AchievementCriteriaTimedTypes type, uint32 entry)
Definition: Player.cpp:13928
void AbandonQuest(uint32 quest_id)
Definition: PlayerQuest.cpp:924

References _player, Player::AbandonQuest(), ACHIEVEMENT_CRITERIA_TYPE_QUEST_ABANDONED, ACHIEVEMENT_TIMED_TYPE_QUEST, CHAR_UPD_QUEST_TRACK_ABANDON_TIME, CharacterDatabase, CONFIG_QUEST_ENABLE_QUEST_TRACKER, ObjectGuid::GetCounter(), Object::GetGUID(), Player::GetQuestSlotQuestId(), Player::HasPvPForcingQuest(), PvPInfo::IsHostile, PvPInfo::IsInHostileArea, LOG_DEBUG, MAX_QUEST_LOG_SIZE, Player::pvpInfo, QUEST_FLAGS_FLAGS_PVP, QUEST_SPECIAL_FLAGS_TIMED, Player::RemoveActiveQuest(), Player::RemoveTimedAchievement(), Player::RemoveTimedQuest(), Player::SetQuestSlot(), sObjectMgr, sScriptMgr, sWorld, Player::TakeQuestSourceItem(), ObjectGuid::ToString(), Player::UpdateAchievementCriteria(), and Player::UpdatePvPState().

Referenced by OpcodeTable::Initialize().

◆ HandleQuestLogSwapQuest()

void WorldSession::HandleQuestLogSwapQuest ( WorldPacket recvData)
388{
389 uint8 slot1, slot2;
390 recvData >> slot1 >> slot2;
391
392 if (slot1 == slot2 || slot1 >= MAX_QUEST_LOG_SIZE || slot2 >= MAX_QUEST_LOG_SIZE)
393 return;
394
395 LOG_DEBUG("network", "WORLD: Received CMSG_QUESTLOG_SWAP_QUEST slot 1 = {}, slot 2 = {}", slot1, slot2);
396
397 GetPlayer()->SwapQuestSlot(slot1, slot2);
398}
void SwapQuestSlot(uint16 slot1, uint16 slot2)
Definition: Player.h:1498

References GetPlayer(), LOG_DEBUG, MAX_QUEST_LOG_SIZE, and Player::SwapQuestSlot().

Referenced by OpcodeTable::Initialize().

◆ HandleQuestPOIQuery()

void WorldSession::HandleQuestPOIQuery ( WorldPacket recvData)
421{
422 uint32 count;
423 recvData >> count; // quest count, max=25
424
425 if (count > MAX_QUEST_LOG_SIZE)
426 {
427 recvData.rfinish();
428 return;
429 }
430
431 // Read quest ids and add the in a unordered_set so we don't send POIs for the same quest multiple times
432 std::unordered_set<uint32> questIds;
433 for (uint32 i = 0; i < count; ++i)
434 questIds.insert(recvData.read<uint32>()); // quest id
435
436 WorldPacket data(SMSG_QUEST_POI_QUERY_RESPONSE, 4 + (4 + 4)*questIds.size());
437 data << uint32(questIds.size()); // count
438
439 for (std::unordered_set<uint32>::const_iterator itr = questIds.begin(); itr != questIds.end(); ++itr)
440 {
441 uint32 questId = *itr;
442 bool questOk = false;
443
444 uint16 questSlot = _player->FindQuestSlot(questId);
445
446 if (questSlot != MAX_QUEST_LOG_SIZE)
447 questOk = _player->GetQuestSlotQuestId(questSlot) == questId;
448
449 if (questOk)
450 {
451 QuestPOIVector const* POI = sObjectMgr->GetQuestPOIVector(questId);
452
453 if (POI)
454 {
455 data << uint32(questId); // quest ID
456 data << uint32(POI->size()); // POI count
457
458 for (QuestPOIVector::const_iterator itr = POI->begin(); itr != POI->end(); ++itr)
459 {
460 data << uint32(itr->Id); // POI index
461 data << int32(itr->ObjectiveIndex); // objective index
462 data << uint32(itr->MapId); // mapid
463 data << uint32(itr->AreaId); // areaid
464 data << uint32(itr->FloorId); // floorid
465 data << uint32(itr->Unk3); // unknown
466 data << uint32(itr->Unk4); // unknown
467 data << uint32(itr->points.size()); // POI points count
468
469 for (std::vector<QuestPOIPoint>::const_iterator itr2 = itr->points.begin(); itr2 != itr->points.end(); ++itr2)
470 {
471 data << int32(itr2->x); // POI point x
472 data << int32(itr2->y); // POI point y
473 }
474 }
475 }
476 else
477 {
478 data << uint32(questId); // quest ID
479 data << uint32(0); // POI count
480 }
481 }
482 else
483 {
484 data << uint32(questId); // quest ID
485 data << uint32(0); // POI count
486 }
487 }
488
489 SendPacket(&data);
490}
std::vector< QuestPOI > QuestPOIVector
Definition: ObjectMgr.h:659
@ SMSG_QUEST_POI_QUERY_RESPONSE
Definition: Opcodes.h:514
uint16 FindQuestSlot(uint32 quest_id) const
Definition: PlayerQuest.cpp:1776

References _player, Player::FindQuestSlot(), Player::GetQuestSlotQuestId(), MAX_QUEST_LOG_SIZE, ByteBuffer::read(), ByteBuffer::rfinish(), SendPacket(), SMSG_QUEST_POI_QUERY_RESPONSE, and sObjectMgr.

Referenced by OpcodeTable::Initialize().

◆ HandleQuestPushResult()

void WorldSession::HandleQuestPushResult ( WorldPacket recvPacket)
619{
620 ObjectGuid guid;
621 uint32 questId;
622 uint8 msg;
623 recvPacket >> guid >> questId >> msg;
624
625 if (_player->GetDivider() && _player->GetDivider() == guid)
626 {
628 {
629 WorldPacket data(MSG_QUEST_PUSH_RESULT, 8 + 4 + 1);
630 data << _player->GetGUID();
631 data << uint8(msg); // valid values: 0-8
632 player->GetSession()->SendPacket(&data);
634 }
635 }
636}
@ MSG_QUEST_PUSH_RESULT
Definition: Opcodes.h:660

References _player, Player::GetDivider(), Object::GetGUID(), ObjectAccessor::GetPlayer(), MSG_QUEST_PUSH_RESULT, and Player::SetDivider().

Referenced by OpcodeTable::Initialize().

◆ HandleQuestQueryOpcode()

void WorldSession::HandleQuestQueryOpcode ( WorldPacket recvPacket)
239{
240 if (!_player)
241 return;
242
243 uint32 questId;
244 recvData >> questId;
245 LOG_DEBUG("network", "WORLD: Received CMSG_QUEST_QUERY quest = {}", questId);
246
247 if (Quest const* quest = sObjectMgr->GetQuestTemplate(questId))
249}
void SendQuestQueryResponse(Quest const *quest) const
Definition: GossipDef.cpp:507

References _player, LOG_DEBUG, Player::PlayerTalkClass, PlayerMenu::SendQuestQueryResponse(), and sObjectMgr.

Referenced by OpcodeTable::Initialize().

◆ HandleRaidReadyCheckFinishedOpcode()

void WorldSession::HandleRaidReadyCheckFinishedOpcode ( WorldPacket recvData)
755{
756 Group* group = GetPlayer()->GetGroup();
757 if (!group)
758 return;
759
760 if (!group->IsLeader(GetPlayer()->GetGUID()) && !group->IsAssistant(GetPlayer()->GetGUID()))
761 return;
762
764 group->BroadcastPacket(&data, true, -1);
765}
@ MSG_RAID_READY_CHECK_FINISHED
Definition: Opcodes.h:996

References Group::BroadcastPacket(), Player::GetGroup(), GetPlayer(), Group::IsAssistant(), Group::IsLeader(), and MSG_RAID_READY_CHECK_FINISHED.

Referenced by OpcodeTable::Initialize().

◆ HandleRaidReadyCheckOpcode()

void WorldSession::HandleRaidReadyCheckOpcode ( WorldPacket recvData)

error handling

711{
712 Group* group = GetPlayer()->GetGroup();
713 if (!group)
714 return;
715
716 if (recvData.empty()) // request
717 {
719 if (!group->IsLeader(GetPlayer()->GetGUID()) && !group->IsAssistant(GetPlayer()->GetGUID()))
720 return;
721 /********************/
722
723 // Check if Ready Check in BG is enabled
725 {
726 // Check if player is in BG
727 if (_player->InBattleground())
728 {
730 return;
731 }
732 }
733
734 // everything's fine, do it
736 data << GetPlayer()->GetGUID();
737 group->BroadcastPacket(&data, false, -1);
738
739 group->OfflineReadyCheck();
740 }
741 else // answer
742 {
743 uint8 state;
744 recvData >> state;
745
746 // everything's fine, do it
748 data << GetPlayer()->GetGUID();
749 data << uint8(state);
750 group->BroadcastReadyCheck(&data);
751 }
752}
@ CONFIG_BATTLEGROUND_DISABLE_READY_CHECK_IN_BG
Definition: IWorld.h:110
@ LANG_BG_READY_CHECK_ERROR
Definition: Language.h:1324
@ MSG_RAID_READY_CHECK
Definition: Opcodes.h:832
@ MSG_RAID_READY_CHECK_CONFIRM
Definition: Opcodes.h:972
void BroadcastReadyCheck(WorldPacket const *packet)
Definition: Group.cpp:1770
void OfflineReadyCheck()
Definition: Group.cpp:1781
bool empty() const
Definition: ByteBuffer.h:445

References _player, Group::BroadcastPacket(), Group::BroadcastReadyCheck(), CONFIG_BATTLEGROUND_DISABLE_READY_CHECK_IN_BG, ByteBuffer::empty(), Player::GetGroup(), Object::GetGUID(), GetPlayer(), Player::GetSession(), Player::InBattleground(), Group::IsAssistant(), Group::IsLeader(), LANG_BG_READY_CHECK_ERROR, MSG_RAID_READY_CHECK, MSG_RAID_READY_CHECK_CONFIRM, Group::OfflineReadyCheck(), ChatHandler::SendNotification(), and sWorld.

Referenced by OpcodeTable::Initialize().

◆ HandleRaidTargetUpdateOpcode()

void WorldSession::HandleRaidTargetUpdateOpcode ( WorldPacket recvData)

error handling

561{
562 Group* group = GetPlayer()->GetGroup();
563 if (!group)
564 return;
565
566 uint8 x;
567 recvData >> x;
568
570 /********************/
571
572 // everything's fine, do it
573 if (x == 0xFF) // target icon request
574 {
575 group->SendTargetIconList(this);
576 }
577 else // target icon update
578 {
579 if (group->isRaidGroup() && !group->IsLeader(GetPlayer()->GetGUID()) && !group->IsAssistant(GetPlayer()->GetGUID()))
580 return;
581
582 ObjectGuid guid;
583 recvData >> guid;
584
585 if (guid.IsPlayer())
586 {
588
589 if (!target || target->IsHostileTo(GetPlayer()))
590 return;
591 }
592
593 group->SetTargetIcon(x, _player->GetGUID(), guid);
594 }
595}
void SendTargetIconList(WorldSession *session)
Definition: Group.cpp:1645
void SetTargetIcon(uint8 id, ObjectGuid whoGuid, ObjectGuid targetGuid)
Definition: Group.cpp:1624

References _player, ObjectAccessor::FindConnectedPlayer(), Player::GetGroup(), Object::GetGUID(), GetPlayer(), Group::IsAssistant(), Unit::IsHostileTo(), Group::IsLeader(), ObjectGuid::IsPlayer(), Group::isRaidGroup(), Group::SendTargetIconList(), and Group::SetTargetIcon().

Referenced by OpcodeTable::Initialize().

◆ HandleRandomRollOpcode()

void WorldSession::HandleRandomRollOpcode ( WorldPackets::Misc::RandomRollClient packet)

error handling

546{
547 uint32 minimum, maximum;
548 minimum = packet.Min;
549 maximum = packet.Max;
550
552 if (minimum > maximum || maximum > 10000) // < 32768 for urand call
553 {
554 return;
555 }
556
557 GetPlayer()->DoRandomRoll(minimum, maximum);
558}
uint32 DoRandomRoll(uint32 minimum, uint32 maximum)
Definition: Player.cpp:16181
uint32 Min
Definition: MiscPackets.h:103
uint32 Max
Definition: MiscPackets.h:104

References Player::DoRandomRoll(), GetPlayer(), WorldPackets::Misc::RandomRollClient::Max, and WorldPackets::Misc::RandomRollClient::Min.

Referenced by OpcodeTable::Initialize().

◆ HandleReadItem()

void WorldSession::HandleReadItem ( WorldPacket recvPacket)
697{
698 //LOG_DEBUG("network.opcode", "WORLD: CMSG_READ_ITEM");
699
700 uint8 bag, slot;
701 recvData >> bag >> slot;
702
703 //LOG_DEBUG("network.opcode", "STORAGE: Read bag = {}, slot = {}", bag, slot);
704 Item* pItem = _player->GetItemByPos(bag, slot);
705
706 if (pItem && pItem->GetTemplate()->PageText)
707 {
708 WorldPacket data;
709
710 InventoryResult msg = _player->CanUseItem(pItem);
711 if (msg == EQUIP_ERR_OK)
712 {
714 LOG_DEBUG("network.opcode", "STORAGE: Item page sent");
715 }
716 else
717 {
719 LOG_DEBUG("network.opcode", "STORAGE: Unable to read item");
720 _player->SendEquipError(msg, pItem, nullptr);
721 }
722 data << pItem->GetGUID();
723 SendPacket(&data);
724 }
725 else
727}
@ SMSG_READ_ITEM_FAILED
Definition: Opcodes.h:205
@ SMSG_READ_ITEM_OK
Definition: Opcodes.h:204
InventoryResult CanUseItem(Item *pItem, bool not_loading=true) const
Definition: PlayerStorage.cpp:2221

References _player, Player::CanUseItem(), EQUIP_ERR_ITEM_NOT_FOUND, EQUIP_ERR_OK, Object::GetGUID(), Player::GetItemByPos(), Item::GetTemplate(), WorldPacket::Initialize(), LOG_DEBUG, ItemTemplate::PageText, Player::SendEquipError(), SendPacket(), SMSG_READ_ITEM_FAILED, and SMSG_READ_ITEM_OK.

Referenced by OpcodeTable::Initialize().

◆ HandleReadyForAccountDataTimes()

void WorldSession::HandleReadyForAccountDataTimes ( WorldPacket recvData)
1644{
1645 // empty opcode
1646 LOG_DEBUG("network", "WORLD: CMSG_READY_FOR_ACCOUNT_DATA_TIMES");
1647
1649}
#define GLOBAL_CACHE_MASK
Definition: WorldSession.h:178

References GLOBAL_CACHE_MASK, LOG_DEBUG, and SendAccountDataTimes().

Referenced by OpcodeTable::Initialize().

◆ HandleRealmSplitOpcode()

void WorldSession::HandleRealmSplitOpcode ( WorldPacket recvData)
1226{
1227 LOG_DEBUG("network", "CMSG_REALM_SPLIT");
1228
1229 uint32 unk;
1230 std::string split_date = "01/01/01";
1231 recv_data >> unk;
1232
1233 WorldPacket data(SMSG_REALM_SPLIT, 4 + 4 + split_date.size() + 1);
1234 data << unk;
1235 data << uint32(0x00000000); // realm split state
1236 // split states:
1237 // 0x0 realm normal
1238 // 0x1 realm split
1239 // 0x2 realm split pending
1240 data << split_date;
1241 SendPacket(&data);
1242}
@ SMSG_REALM_SPLIT
Definition: Opcodes.h:937

References LOG_DEBUG, SendPacket(), and SMSG_REALM_SPLIT.

Referenced by OpcodeTable::Initialize().

◆ HandleReclaimCorpseOpcode()

void WorldSession::HandleReclaimCorpseOpcode ( WorldPacket recvPacket)
635{
636 ObjectGuid guid;
637 recv_data >> guid;
638
639 if (_player->IsAlive())
640 return;
641
642 // do not allow corpse reclaim in arena
643 if (_player->InArena())
644 return;
645
646 // body not released yet
648 return;
649
650 Corpse* corpse = _player->GetCorpse();
651 if (!corpse)
652 return;
653
654 // prevent resurrect before 30-sec delay after body release not finished
655 if (time_t(corpse->GetGhostTime() + _player->GetCorpseReclaimDelay(corpse->GetType() == CORPSE_RESURRECTABLE_PVP)) > time_t(GameTime::GetGameTime().count()))
656 return;
657
659 return;
660
661 // resurrect
663
664 // spawn bones
666}
#define CORPSE_RECLAIM_RADIUS
Definition: Corpse.h:35
@ CORPSE_RESURRECTABLE_PVP
Definition: Corpse.h:30
time_t const & GetGhostTime() const
Definition: Corpse.h:70
Corpse * GetCorpse() const
Definition: Player.cpp:4692
uint32 GetCorpseReclaimDelay(bool pvp) const
Definition: Player.cpp:12921
bool InArena() const
Definition: Player.cpp:12296

References _player, CORPSE_RECLAIM_RADIUS, CORPSE_RESURRECTABLE_PVP, Player::GetCorpse(), Player::GetCorpseReclaimDelay(), GameTime::GetGameTime(), Corpse::GetGhostTime(), Corpse::GetType(), Player::HasPlayerFlag(), Player::InArena(), Player::InBattleground(), Unit::IsAlive(), WorldObject::IsWithinDistInMap(), PLAYER_FLAGS_GHOST, Player::ResurrectPlayer(), and Player::SpawnCorpseBones().

Referenced by OpcodeTable::Initialize().

◆ HandleRemoveGlyph()

void WorldSession::HandleRemoveGlyph ( WorldPacket recvData)
1574{
1575 uint32 slot;
1576 recvData >> slot;
1577
1578 if (slot >= MAX_GLYPH_SLOT_INDEX)
1579 {
1580 LOG_DEBUG("network", "Client sent wrong glyph slot number in opcode CMSG_REMOVE_GLYPH {}", slot);
1581 return;
1582 }
1583
1584 if (uint32 glyph = _player->GetGlyph(slot))
1585 {
1586 if (GlyphPropertiesEntry const* glyphEntry = sGlyphPropertiesStore.LookupEntry(glyph))
1587 {
1588 _player->RemoveAurasDueToSpell(glyphEntry->SpellId);
1589
1590 // Removed any triggered auras
1591 Unit::AuraMap& ownedAuras = _player->GetOwnedAuras();
1592 for (Unit::AuraMap::iterator iter = ownedAuras.begin(); iter != ownedAuras.end();)
1593 {
1594 Aura* aura = iter->second;
1595 if (SpellInfo const* triggeredByAuraSpellInfo = aura->GetTriggeredByAuraSpellInfo())
1596 {
1597 if (triggeredByAuraSpellInfo->Id == glyphEntry->SpellId)
1598 {
1599 _player->RemoveOwnedAura(iter);
1600 continue;
1601 }
1602 }
1603 ++iter;
1604 }
1605
1606 _player->SendLearnPacket(glyphEntry->SpellId, false); // Send packet to properly handle client-side spell tooltips
1607 _player->SetGlyph(slot, 0, true);
1609 }
1610 }
1611}
DBCStorage< GlyphPropertiesEntry > sGlyphPropertiesStore(GlyphPropertiesfmt)
#define MAX_GLYPH_SLOT_INDEX
Definition: SharedDefines.h:676
void SendLearnPacket(uint32 spellId, bool learn)
Definition: Player.cpp:3019
uint32 GetGlyph(uint8 slot) const
Definition: Player.h:1752
void SetGlyph(uint8 slot, uint32 glyph, bool save)
Definition: Player.h:1744
std::multimap< uint32, Aura * > AuraMap
Definition: Unit.h:635
void RemoveAurasDueToSpell(uint32 spellId, ObjectGuid casterGUID=ObjectGuid::Empty, uint8 reqEffMask=0, AuraRemoveMode removeMode=AURA_REMOVE_BY_DEFAULT)
Definition: Unit.cpp:4890
AuraMap & GetOwnedAuras()
Definition: Unit.h:1321
SpellInfo const * GetTriggeredByAuraSpellInfo() const
Definition: SpellAuras.cpp:2761
Definition: DBCStructure.h:1020

References _player, Player::GetGlyph(), Unit::GetOwnedAuras(), Aura::GetTriggeredByAuraSpellInfo(), LOG_DEBUG, MAX_GLYPH_SLOT_INDEX, Unit::RemoveAurasDueToSpell(), Unit::RemoveOwnedAura(), Player::SendLearnPacket(), Player::SendTalentsInfoData(), Player::SetGlyph(), and sGlyphPropertiesStore.

Referenced by OpcodeTable::Initialize().

◆ HandleRepairItemOpcode()

void WorldSession::HandleRepairItemOpcode ( WorldPacket recvPacket)
885{
886 LOG_DEBUG("network", "WORLD: CMSG_REPAIR_ITEM");
887
888 ObjectGuid npcGUID, itemGUID;
889 uint8 guildBank; // new in 2.3.2, bool that means from guild bank money
890
891 recvData >> npcGUID >> itemGUID >> guildBank;
892
894 if (!unit)
895 {
896 LOG_DEBUG("network", "WORLD: HandleRepairItemOpcode - Unit ({}) not found or you can not interact with him.", npcGUID.ToString());
897 return;
898 }
899
900 // remove fake death
901 if (GetPlayer()->HasUnitState(UNIT_STATE_DIED))
903
904 // reputation discount
905 float discountMod = _player->GetReputationPriceDiscount(unit);
906
907 sScriptMgr->OnBeforePlayerDurabilityRepair(_player, npcGUID, itemGUID, discountMod, guildBank);
908
909 if (itemGUID)
910 {
911 LOG_DEBUG("network", "ITEM: Repair item, item {}, npc {}", itemGUID.ToString(), npcGUID.ToString());
912
913 Item* item = _player->GetItemByGuid(itemGUID);
914 if (item)
915 _player->DurabilityRepair(item->GetPos(), true, discountMod, guildBank);
916 }
917 else
918 {
919 LOG_DEBUG("network", "ITEM: Repair all items, npc {}", npcGUID.ToString());
920 _player->DurabilityRepairAll(true, discountMod, guildBank);
921 }
922}
@ UNIT_NPC_FLAG_REPAIR
Definition: UnitDefines.h:306
float GetReputationPriceDiscount(Creature const *creature) const
Definition: Player.cpp:12335
uint32 DurabilityRepairAll(bool cost, float discountMod, bool guildBank)
Definition: Player.cpp:4810
uint32 DurabilityRepair(uint16 pos, bool cost, float discountMod, bool guildBank)
Definition: Player.cpp:4826

References _player, Player::DurabilityRepair(), Player::DurabilityRepairAll(), Player::GetItemByGuid(), Player::GetNPCIfCanInteractWith(), GetPlayer(), Item::GetPos(), Player::GetReputationPriceDiscount(), LOG_DEBUG, Unit::RemoveAurasByType(), SPELL_AURA_FEIGN_DEATH, sScriptMgr, ObjectGuid::ToString(), UNIT_NPC_FLAG_REPAIR, and UNIT_STATE_DIED.

Referenced by OpcodeTable::Initialize().

◆ HandleRepopRequestOpcode()

void WorldSession::HandleRepopRequestOpcode ( WorldPacket recvPacket)
57{
58 LOG_DEBUG("network", "WORLD: Recvd CMSG_REPOP_REQUEST Message");
59
60 recv_data.read_skip<uint8>();
61
63 return;
64
66 return; // silently return, client should display the error by itself
67
68 // the world update order is sessions, players, creatures
69 // the netcode runs in parallel with all of these
70 // creatures can kill players
71 // so if the server is lagging enough the player can
72 // release spirit after he's killed but before he is updated
73 if (GetPlayer()->getDeathState() == DeathState::JustDied)
74 {
75 LOG_DEBUG("network", "HandleRepopRequestOpcode: got request after player {} ({}) was killed and before he was updated",
76 GetPlayer()->GetName(), GetPlayer()->GetGUID().ToString());
78 }
79
80 //this is spirit release confirm?
81 GetPlayer()->RemovePet(nullptr, PET_SAVE_NOT_IN_SLOT, true);
84}
@ PET_SAVE_NOT_IN_SLOT
Definition: PetDefines.h:45
@ SPELL_AURA_PREVENT_RESURRECTION
Definition: SpellAuraDefines.h:377
DeathState getDeathState()
Definition: Unit.h:1219

References Player::BuildPlayerRepop(), Unit::getDeathState(), GetPlayer(), Unit::HasAuraType(), Player::HasPlayerFlag(), Unit::IsAlive(), Player::KillPlayer(), LOG_DEBUG, PET_SAVE_NOT_IN_SLOT, PLAYER_FLAGS_GHOST, ByteBuffer::read_skip(), Player::RemovePet(), Player::RepopAtGraveyard(), and SPELL_AURA_PREVENT_RESURRECTION.

Referenced by OpcodeTable::Initialize().

◆ HandleReportLag()

void WorldSession::HandleReportLag ( WorldPacket recvPacket)
257{
258 // just put the lag report into the database...
259 // can't think of anything else to do with it
260 uint32 lagType, mapId;
261 recv_data >> lagType;
262 recv_data >> mapId;
263 float x, y, z;
264 recv_data >> x;
265 recv_data >> y;
266 recv_data >> z;
267
269 stmt->SetData(0, GetPlayer()->GetGUID().GetCounter());
270 stmt->SetData (1, lagType);
271 stmt->SetData(2, mapId);
272 stmt->SetData (3, x);
273 stmt->SetData (4, y);
274 stmt->SetData (5, z);
275 stmt->SetData(6, GetLatency());
276 stmt->SetData(7, GameTime::GetGameTime().count());
277 CharacterDatabase.Execute(stmt);
278}
@ CHAR_INS_LAG_REPORT
Definition: CharacterDatabase.h:269
uint32 GetLatency() const
Definition: WorldSession.h:502

References CHAR_INS_LAG_REPORT, CharacterDatabase, GameTime::GetGameTime(), GetLatency(), GetPlayer(), and PreparedStatementBase::SetData().

Referenced by OpcodeTable::Initialize().

◆ HandleReportPvPAFK()

void WorldSession::HandleReportPvPAFK ( WorldPacket recvData)
903{
904 ObjectGuid playerGuid;
905 recvData >> playerGuid;
906 Player* reportedPlayer = ObjectAccessor::FindPlayer(playerGuid);
907
908 if (!reportedPlayer)
909 {
910 LOG_DEBUG("bg.battleground", "WorldSession::HandleReportPvPAFK: player not found");
911 return;
912 }
913
914 LOG_DEBUG("bg.battleground", "WorldSession::HandleReportPvPAFK: {} reported {}", _player->GetName(), reportedPlayer->GetName());
915
916 reportedPlayer->ReportedAfkBy(_player);
917}
void ReportedAfkBy(Player *reporter)
This player has been blamed to be inactive in a battleground.
Definition: Player.cpp:11377

References _player, ObjectAccessor::FindPlayer(), WorldObject::GetName(), LOG_DEBUG, and Player::ReportedAfkBy().

Referenced by OpcodeTable::Initialize().

◆ HandleRequestAccountData()

void WorldSession::HandleRequestAccountData ( WorldPacket recvPacket)
901{
902 uint32 type;
903 recv_data >> type;
904
905 LOG_DEBUG("network", "RAD: type {}", type);
906
907 if (type >= NUM_ACCOUNT_DATA_TYPES)
908 return;
909
911
912 uint32 size = adata->Data.size();
913
914 uLongf destSize = compressBound(size);
915
916 ByteBuffer dest;
917 dest.resize(destSize);
918
919 if (size && compress(dest.contents(), &destSize, (uint8 const*)adata->Data.c_str(), size) != Z_OK)
920 {
921 LOG_DEBUG("network", "RAD: Failed to compress account data");
922 return;
923 }
924
925 dest.resize(destSize);
926
927 WorldPacket data(SMSG_UPDATE_ACCOUNT_DATA, 8 + 4 + 4 + 4 + destSize);
928 data << (_player ? _player->GetGUID() : ObjectGuid::Empty); // player guid
929 data << uint32(type); // type (0-7)
930 data << uint32(adata->Time); // unix time
931 data << uint32(size); // decompressed length
932 data.append(dest); // compressed data
933 SendPacket(&data);
934}
AccountDataType
Definition: WorldSession.h:165
#define NUM_ACCOUNT_DATA_TYPES
Definition: WorldSession.h:176
@ SMSG_UPDATE_ACCOUNT_DATA
Definition: Opcodes.h:554
Definition: WorldSession.h:182
time_t Time
Definition: WorldSession.h:185
std::string Data
Definition: WorldSession.h:186
AccountData * GetAccountData(AccountDataType type)
Definition: WorldSession.h:450

References _player, ByteBuffer::append(), ByteBuffer::contents(), AccountData::Data, ObjectGuid::Empty, GetAccountData(), Object::GetGUID(), LOG_DEBUG, NUM_ACCOUNT_DATA_TYPES, ByteBuffer::resize(), SendPacket(), SMSG_UPDATE_ACCOUNT_DATA, and AccountData::Time.

Referenced by OpcodeTable::Initialize().

◆ HandleRequestPartyMemberStatsOpcode()

void WorldSession::HandleRequestPartyMemberStatsOpcode ( WorldPacket recvData)
954{
955 ObjectGuid Guid;
956 recvData >> Guid;
957
958 Player* player = HashMapHolder<Player>::Find(Guid);
959 if (!player || !player->IsInSameRaidWith(_player))
960 {
962 data << uint8(0); // only for SMSG_PARTY_MEMBER_STATS_FULL, probably arena/bg related
963 data << Guid.WriteAsPacked();
966 SendPacket(&data);
967 return;
968 }
969
970 Pet* pet = player->GetPet();
971 Powers powerType = player->getPowerType();
972
973 WorldPacket data(SMSG_PARTY_MEMBER_STATS_FULL, 4 + 2 + 2 + 2 + 1 + 2 * 6 + 8 + 1 + 8);
974 data << uint8(0); // only for SMSG_PARTY_MEMBER_STATS_FULL, probably arena/bg related
975 data << player->GetPackGUID();
976
981
982 if (powerType != POWER_MANA)
983 updateFlags |= GROUP_UPDATE_FLAG_POWER_TYPE;
984
985 if (pet)
988
989 if (player->GetVehicle())
990 updateFlags |= GROUP_UPDATE_FLAG_VEHICLE_SEAT;
991
992 uint16 playerStatus = MEMBER_STATUS_ONLINE;
993 if (player->IsPvP())
994 playerStatus |= MEMBER_STATUS_PVP;
995
996 if (!player->IsAlive())
997 {
999 playerStatus |= MEMBER_STATUS_GHOST;
1000 else
1001 playerStatus |= MEMBER_STATUS_DEAD;
1002 }
1003
1004 if (player->IsFFAPvP())
1005 playerStatus |= MEMBER_STATUS_PVP_FFA;
1006
1007 if (player->isAFK())
1008 playerStatus |= MEMBER_STATUS_AFK;
1009
1010 if (player->isDND())
1011 playerStatus |= MEMBER_STATUS_DND;
1012
1013 data << uint32(updateFlags);
1014 data << uint16(playerStatus); // GROUP_UPDATE_FLAG_STATUS
1015 data << uint32(player->GetHealth()); // GROUP_UPDATE_FLAG_CUR_HP
1016 data << uint32(player->GetMaxHealth()); // GROUP_UPDATE_FLAG_MAX_HP
1017 if (updateFlags & GROUP_UPDATE_FLAG_POWER_TYPE)
1018 data << uint8(powerType);
1019
1020 data << uint16(player->GetPower(powerType)); // GROUP_UPDATE_FLAG_CUR_POWER
1021 data << uint16(player->GetMaxPower(powerType)); // GROUP_UPDATE_FLAG_MAX_POWER
1022 data << uint16(player->GetLevel()); // GROUP_UPDATE_FLAG_LEVEL
1023 data << uint16(player->GetZoneId()); // GROUP_UPDATE_FLAG_ZONE
1024 data << uint16(player->GetPositionX()); // GROUP_UPDATE_FLAG_POSITION
1025 data << uint16(player->GetPositionY()); // GROUP_UPDATE_FLAG_POSITION
1026
1027 uint64 auraMask = 0;
1028 std::size_t maskPos = data.wpos();
1029 data << uint64(auraMask); // placeholder
1030 for (uint8 i = 0; i < MAX_AURAS_GROUP_UPDATE; ++i)
1031 {
1032 if (AuraApplication const* aurApp = player->GetVisibleAura(i))
1033 {
1034 auraMask |= uint64(1) << i;
1035 data << uint32(aurApp->GetBase()->GetId());
1036 data << uint8(aurApp->GetFlags());
1037 }
1038 }
1039
1040 data.put<uint64>(maskPos, auraMask); // GROUP_UPDATE_FLAG_AURAS
1041
1042 if (pet && (updateFlags & GROUP_UPDATE_FLAG_PET_GUID))
1043 data << pet->GetGUID();
1044
1045 data << std::string(pet ? pet->GetName() : ""); // GROUP_UPDATE_FLAG_PET_NAME
1046 data << uint16(pet ? pet->GetDisplayId() : 0); // GROUP_UPDATE_FLAG_PET_MODEL_ID
1047
1048 if (pet && (updateFlags & GROUP_UPDATE_FLAG_PET_CUR_HP))
1049 data << uint32(pet->GetHealth());
1050
1051 if (pet && (updateFlags & GROUP_UPDATE_FLAG_PET_MAX_HP))
1052 data << uint32(pet->GetMaxHealth());
1053
1054 if (pet && (updateFlags & GROUP_UPDATE_FLAG_PET_POWER_TYPE))
1055 data << (uint8)pet->getPowerType();
1056
1057 if (pet && (updateFlags & GROUP_UPDATE_FLAG_PET_CUR_POWER))
1058 data << uint16(pet->GetPower(pet->getPowerType()));
1059
1060 if (pet && (updateFlags & GROUP_UPDATE_FLAG_PET_MAX_POWER))
1061 data << uint16(pet->GetMaxPower(pet->getPowerType()));
1062
1063 uint64 petAuraMask = 0;
1064 maskPos = data.wpos();
1065 data << uint64(petAuraMask); // placeholder
1066 if (pet)
1067 {
1068 for (uint8 i = 0; i < MAX_AURAS_GROUP_UPDATE; ++i)
1069 {
1070 if (AuraApplication const* aurApp = pet->GetVisibleAura(i))
1071 {
1072 petAuraMask |= uint64(1) << i;
1073 data << uint32(aurApp->GetBase()->GetId());
1074 data << uint8(aurApp->GetFlags());
1075 }
1076 }
1077 }
1078
1079 data.put<uint64>(maskPos, petAuraMask); // GROUP_UPDATE_FLAG_PET_AURAS
1080
1081 if (updateFlags & GROUP_UPDATE_FLAG_VEHICLE_SEAT)
1082 data << uint32(player->GetVehicle()->GetVehicleInfo()->m_seatID[player->m_movementInfo.transport.seat]);
1083
1084 SendPacket(&data);
1085}
@ MEMBER_STATUS_OFFLINE
Definition: Group.h:60
@ POWER_MANA
Definition: SharedDefines.h:269
@ SMSG_PARTY_MEMBER_STATS_FULL
Definition: Opcodes.h:784
VehicleEntry const * GetVehicleInfo() const
Definition: Vehicle.h:38
static T * Find(ObjectGuid guid)
Definition: ObjectAccessor.cpp:53
uint32 m_seatID[MAX_VEHICLE_SEATS]
Definition: DBCStructure.h:2033

References _player, HashMapHolder< T >::Find(), Unit::GetDisplayId(), Object::GetGUID(), Unit::GetHealth(), Unit::GetLevel(), Unit::GetMaxHealth(), Unit::GetMaxPower(), WorldObject::GetName(), Object::GetPackGUID(), Player::GetPet(), Position::GetPositionX(), Position::GetPositionY(), Unit::GetPower(), Unit::getPowerType(), Unit::GetVehicle(), Vehicle::GetVehicleInfo(), Unit::GetVisibleAura(), WorldObject::GetZoneId(), GROUP_UPDATE_FLAG_AURAS, GROUP_UPDATE_FLAG_CUR_HP, GROUP_UPDATE_FLAG_CUR_POWER, GROUP_UPDATE_FLAG_LEVEL, GROUP_UPDATE_FLAG_MAX_HP, GROUP_UPDATE_FLAG_MAX_POWER, GROUP_UPDATE_FLAG_PET_AURAS, GROUP_UPDATE_FLAG_PET_CUR_HP, GROUP_UPDATE_FLAG_PET_CUR_POWER, GROUP_UPDATE_FLAG_PET_GUID, GROUP_UPDATE_FLAG_PET_MAX_HP, GROUP_UPDATE_FLAG_PET_MAX_POWER, GROUP_UPDATE_FLAG_PET_MODEL_ID, GROUP_UPDATE_FLAG_PET_NAME, GROUP_UPDATE_FLAG_PET_POWER_TYPE, GROUP_UPDATE_FLAG_POSITION, GROUP_UPDATE_FLAG_POWER_TYPE, GROUP_UPDATE_FLAG_STATUS, GROUP_UPDATE_FLAG_VEHICLE_SEAT, GROUP_UPDATE_FLAG_ZONE, Player::HasPlayerFlag(), Player::isAFK(), Unit::IsAlive(), Player::isDND(), Player::IsFFAPvP(), Player::IsInSameRaidWith(), Player::IsPvP(), WorldObject::m_movementInfo, VehicleEntry::m_seatID, MAX_AURAS_GROUP_UPDATE, MEMBER_STATUS_AFK, MEMBER_STATUS_DEAD, MEMBER_STATUS_DND, MEMBER_STATUS_GHOST, MEMBER_STATUS_OFFLINE, MEMBER_STATUS_ONLINE, MEMBER_STATUS_PVP, MEMBER_STATUS_PVP_FFA, PLAYER_FLAGS_GHOST, POWER_MANA, ByteBuffer::put(), MovementInfo::TransportInfo::seat, SendPacket(), SMSG_PARTY_MEMBER_STATS_FULL, MovementInfo::transport, ByteBuffer::wpos(), and ObjectGuid::WriteAsPacked().

Referenced by OpcodeTable::Initialize().

◆ HandleRequestPetInfo()

void WorldSession::HandleRequestPetInfo ( WorldPackets::Pet::RequestPetInfo packet)
1587{
1588 /*
1589 LOG_DEBUG("network.opcode", "WORLD: CMSG_REQUEST_PET_INFO");
1590 recv_data.hexlike();
1591 */
1592
1593 if (_player->GetPet())
1595 else if (_player->GetCharm())
1597}
void CharmSpellInitialize()
Definition: Player.cpp:9643

References _player, Player::CharmSpellInitialize(), Unit::GetCharm(), Player::GetPet(), and Player::PetSpellInitialize().

Referenced by OpcodeTable::Initialize().

◆ HandleRequestRaidInfoOpcode()

void WorldSession::HandleRequestRaidInfoOpcode ( WorldPacket recvData)
1088{
1089 // every time the player checks the character screen
1091}
void SendRaidInfo()
Definition: PlayerStorage.cpp:6521

References _player, and Player::SendRaidInfo().

Referenced by OpcodeTable::Initialize().

◆ HandleRequestVehicleExit()

void WorldSession::HandleRequestVehicleExit ( WorldPacket recvData)
227{
228 LOG_DEBUG("network", "WORLD: Recvd CMSG_REQUEST_VEHICLE_EXIT");
229
230 if (Vehicle* vehicle = GetPlayer()->GetVehicle())
231 {
232 if (VehicleSeatEntry const* seat = vehicle->GetSeatForPassenger(GetPlayer()))
233 {
234 if (seat->CanEnterOrExit())
236 else
237 LOG_ERROR("network.opcode", "Player {} tried to exit vehicle, but seatflags {} (ID: {}) don't permit that.",
238 GetPlayer()->GetGUID().ToString(), seat->m_ID, seat->m_flags);
239 }
240 }
241}

References Unit::ExitVehicle(), GetPlayer(), LOG_DEBUG, and LOG_ERROR.

Referenced by OpcodeTable::Initialize().

◆ HandleResetInstancesOpcode()

void WorldSession::HandleResetInstancesOpcode ( WorldPacket recvData)
1313{
1314 LOG_DEBUG("network", "WORLD: CMSG_RESET_INSTANCES");
1315
1316 if (Group* group = _player->GetGroup())
1317 {
1318 if (group->IsLeader(_player->GetGUID()))
1319 group->ResetInstances(INSTANCE_RESET_ALL, false, _player);
1320 }
1321 else
1323}
@ INSTANCE_RESET_ALL
Definition: Map.h:811
static void ResetInstances(ObjectGuid guid, uint8 method, bool isRaid)
Reset all solo instances and optionally send a message on success for each.
Definition: PlayerMisc.cpp:195

References _player, Player::GetGroup(), Object::GetGUID(), INSTANCE_RESET_ALL, LOG_DEBUG, and Player::ResetInstances().

Referenced by OpcodeTable::Initialize().

◆ HandleResurrectResponseOpcode()

void WorldSession::HandleResurrectResponseOpcode ( WorldPacket recvPacket)
669{
670 ObjectGuid guid;
671 uint8 status;
672 recv_data >> guid;
673 recv_data >> status;
674
675 // Xinef: Prevent resurrect with prevent resurrection aura
676 if (GetPlayer()->IsAlive() || GetPlayer()->HasAuraType(SPELL_AURA_PREVENT_RESURRECTION))
677 return;
678
679 if (status == 0)
680 {
682 return;
683 }
684
685 if (!GetPlayer()->isResurrectRequestedBy(guid))
686 return;
687
689}
void ResurectUsingRequestData()
Definition: Player.cpp:12827
void clearResurrectRequestData()
Definition: Player.h:1808

References Player::clearResurrectRequestData(), GetPlayer(), Player::ResurectUsingRequestData(), and SPELL_AURA_PREVENT_RESURRECTION.

Referenced by OpcodeTable::Initialize().

◆ HandleSaveGuildEmblemOpcode()

void WorldSession::HandleSaveGuildEmblemOpcode ( WorldPackets::Guild::SaveGuildEmblem packet)
225{
226 EmblemInfo emblemInfo;
227 emblemInfo.ReadPacket(packet);
228
229 LOG_DEBUG("guild", "MSG_SAVE_GUILD_EMBLEM [{}]: Guid: [{}] Style: {}, Color: {}, BorderStyle: {}, BorderColor: {}, BackgroundColor: {}"
230 , GetPlayerInfo(), packet.Vendor.ToString(), emblemInfo.GetStyle()
231 , emblemInfo.GetColor(), emblemInfo.GetBorderStyle()
232 , emblemInfo.GetBorderColor(), emblemInfo.GetBackgroundColor());
233 if (GetPlayer()->GetNPCIfCanInteractWith(packet.Vendor, UNIT_NPC_FLAG_TABARDDESIGNER))
234 {
235 // Remove fake death
236 if (GetPlayer()->HasUnitState(UNIT_STATE_DIED))
238
239 if (Guild* guild = GetPlayer()->GetGuild())
240 guild->HandleSetEmblem(this, emblemInfo);
241 else
242 Guild::SendSaveEmblemResult(this, ERR_GUILDEMBLEM_NOGUILD); // "You are not part of a guild!";
243 }
244 else
245 Guild::SendSaveEmblemResult(this, ERR_GUILDEMBLEM_INVALIDVENDOR); // "That's not an emblem vendor!"
246}
@ ERR_GUILDEMBLEM_INVALIDVENDOR
Definition: Guild.h:228
@ ERR_GUILDEMBLEM_NOGUILD
Definition: Guild.h:225
@ UNIT_NPC_FLAG_TABARDDESIGNER
Definition: UnitDefines.h:313
Definition: Guild.h:242
uint32 GetStyle() const
Definition: Guild.h:250
uint32 GetColor() const
Definition: Guild.h:251
uint32 GetBackgroundColor() const
Definition: Guild.h:254
uint32 GetBorderStyle() const
Definition: Guild.h:252
void ReadPacket(WorldPackets::Guild::SaveGuildEmblem &packet)
Definition: Guild.cpp:683
uint32 GetBorderColor() const
Definition: Guild.h:253
static void SendSaveEmblemResult(WorldSession *session, GuildEmblemError errCode)
Definition: Guild.cpp:125
ObjectGuid Vendor
Definition: GuildPackets.h:605

References ERR_GUILDEMBLEM_INVALIDVENDOR, ERR_GUILDEMBLEM_NOGUILD, EmblemInfo::GetBackgroundColor(), EmblemInfo::GetBorderColor(), EmblemInfo::GetBorderStyle(), EmblemInfo::GetColor(), GetPlayer(), GetPlayerInfo(), EmblemInfo::GetStyle(), LOG_DEBUG, EmblemInfo::ReadPacket(), Unit::RemoveAurasByType(), Guild::SendSaveEmblemResult(), SPELL_AURA_FEIGN_DEATH, ObjectGuid::ToString(), UNIT_NPC_FLAG_TABARDDESIGNER, UNIT_STATE_DIED, and WorldPackets::Guild::SaveGuildEmblem::Vendor.

Referenced by OpcodeTable::Initialize().

◆ HandleSelfResOpcode()

void WorldSession::HandleSelfResOpcode ( WorldPacket recvData)
631{
632 LOG_DEBUG("network", "WORLD: CMSG_SELF_RES"); // empty opcode
633
634 if (SpellInfo const* spell = sSpellMgr->GetSpellInfo(_player->GetUInt32Value(PLAYER_SELF_RES_SPELL)))
635 {
637 {
638 return; // silent return, client should display error by itself and not send this opcode
639 }
640
641 _player->CastSpell(_player, spell->Id);
643 }
644}
@ PLAYER_SELF_RES_SPELL
Definition: UpdateFields.h:370
@ SPELL_ATTR7_BYPASS_NO_RESURRECTION_AURA
Definition: SharedDefines.h:668

References _player, Unit::CastSpell(), Object::GetUInt32Value(), Unit::HasAuraType(), LOG_DEBUG, PLAYER_SELF_RES_SPELL, Unit::SetUInt32Value(), SPELL_ATTR7_BYPASS_NO_RESURRECTION_AURA, SPELL_AURA_PREVENT_RESURRECTION, and sSpellMgr.

Referenced by OpcodeTable::Initialize().

◆ HandleSellItemOpcode()

void WorldSession::HandleSellItemOpcode ( WorldPacket recvPacket)
730{
731 ObjectGuid vendorguid, itemguid;
732 uint32 count;
733
734 recvData >> vendorguid >> itemguid >> count;
735
736 if (!itemguid)
737 return;
738
740 if (!creature)
741 {
742 LOG_DEBUG("network", "WORLD: HandleSellItemOpcode - Unit ({}) not found or you can not interact with him.", vendorguid.ToString());
743 _player->SendSellError(SELL_ERR_CANT_FIND_VENDOR, nullptr, itemguid, 0);
744 return;
745 }
746
748 {
750 return;
751 }
752
753 // remove fake death
754 if (GetPlayer()->HasUnitState(UNIT_STATE_DIED))
756
757 Item* pItem = _player->GetItemByGuid(itemguid);
758 if (pItem)
759 {
760 if (!sScriptMgr->CanSellItem(_player, pItem, creature))
761 return;
762
763 // prevent sell not owner item
764 if (_player->GetGUID() != pItem->GetOwnerGUID())
765 {
766 _player->SendSellError(SELL_ERR_CANT_SELL_ITEM, creature, itemguid, 0);
767 return;
768 }
769
770 // prevent sell non empty bag by drag-and-drop at vendor's item list
771 if (pItem->IsNotEmptyBag())
772 {
773 _player->SendSellError(SELL_ERR_CANT_SELL_ITEM, creature, itemguid, 0);
774 return;
775 }
776
777 // prevent sell currently looted item
778 if (_player->GetLootGUID() == pItem->GetGUID())
779 {
780 _player->SendSellError(SELL_ERR_CANT_SELL_ITEM, creature, itemguid, 0);
781 return;
782 }
783
784 // prevent selling item for sellprice when the item is still refundable
785 // this probably happens when right clicking a refundable item, the client sends both
786 // CMSG_SELL_ITEM and CMSG_REFUND_ITEM (unverified)
787 if (pItem->IsRefundable())
788 return; // Therefore, no feedback to client
789
790 // special case at auto sell (sell all)
791 if (count == 0)
792 {
793 count = pItem->GetCount();
794 }
795 else
796 {
797 // prevent sell more items that exist in stack (possible only not from client)
798 if (count > pItem->GetCount())
799 {
800 _player->SendSellError(SELL_ERR_CANT_SELL_ITEM, creature, itemguid, 0);
801 return;
802 }
803 }
804
805 ItemTemplate const* pProto = pItem->GetTemplate();
806 if (pProto)
807 {
808 if (pProto->SellPrice > 0)
809 {
810 uint32 money = pProto->SellPrice * count;
811 if (_player->GetMoney() >= MAX_MONEY_AMOUNT - money) // prevent exceeding gold limit
812 {
814 _player->SendSellError(SELL_ERR_UNK, creature, itemguid, 0);
815 return;
816 }
817
818 if (sWorld->getBoolConfig(CONFIG_ITEMDELETE_VENDOR))
819 recoveryItem(pItem);
820
821 uint32 maxDurability = pItem->GetUInt32Value(ITEM_FIELD_MAXDURABILITY);
822 if (maxDurability)
823 {
824 uint32 curDurability = pItem->GetUInt32Value(ITEM_FIELD_DURABILITY);
825 uint32 LostDurability = maxDurability - curDurability;
826
827 if (LostDurability > 0)
828 {
829 DurabilityCostsEntry const* dcost = sDurabilityCostsStore.LookupEntry(pProto->ItemLevel);
830 if (!dcost)
831 {
832 _player->SendSellError(SELL_ERR_CANT_SELL_ITEM, creature, itemguid, 0);
833 LOG_ERROR("network.opcode", "WORLD: HandleSellItemOpcode - Wrong item lvl {} for item {} count = {}", pProto->ItemLevel, pItem->GetEntry(), count);
834 return;
835 }
836
837 uint32 dQualitymodEntryId = (pProto->Quality + 1) * 2;
838 DurabilityQualityEntry const* dQualitymodEntry = sDurabilityQualityStore.LookupEntry(dQualitymodEntryId);
839 if (!dQualitymodEntry)
840 {
841 _player->SendSellError(SELL_ERR_CANT_SELL_ITEM, creature, itemguid, 0);
842 LOG_ERROR("network.opcode", "WORLD: HandleSellItemOpcode - Wrong dQualityModEntry {} for item {} count = {}", dQualitymodEntryId, pItem->GetEntry(), count);
843 return;
844 }
845
846 uint32 dmultiplier = dcost->multiplier[ItemSubClassToDurabilityMultiplierId(pProto->Class, pProto->SubClass)];
847 uint32 refund = uint32(std::ceil(LostDurability * dmultiplier * double(dQualitymodEntry->quality_mod)));
848
849 if (!refund)
850 {
851 refund = 1;
852 }
853
854 //starter items can cost more to refund than vendorprice
855 if (refund > money)
856 {
857 money = 1;
858 }
859 else
860 {
861 money -= refund;
862 }
863 }
864 }
865
866 if (count < pItem->GetCount()) // need split items
867 {
868 Item* pNewItem = pItem->CloneItem(count, _player);
869 if (!pNewItem)
870 {
871 LOG_ERROR("network.opcode", "WORLD: HandleSellItemOpcode - could not create clone of item {}; count = {}", pItem->GetEntry(), count);
872 _player->SendSellError(SELL_ERR_CANT_SELL_ITEM, creature, itemguid, 0);
873 return;
874 }
875
877
878 pItem->SetCount(pItem->GetCount() - count);
879 _player->ItemRemovedQuestCheck(pItem->GetEntry(), count);
880 if (_player->IsInWorld())
883
884 _player->AddItemToBuyBackSlot(pNewItem, money);
885 if (_player->IsInWorld())
886 pNewItem->SendUpdateToPlayer(_player);
887 }
888 else
889 {
890 _player->ItemRemovedQuestCheck(pItem->GetEntry(), pItem->GetCount());
891 _player->RemoveItem(pItem->GetBagSlot(), pItem->GetSlot(), true);
893 _player->AddItemToBuyBackSlot(pItem, money);
895 }
896
897 _player->ModifyMoney(money);
899 }
900 else
901 _player->SendSellError(SELL_ERR_CANT_SELL_ITEM, creature, itemguid, 0);
902 return;
903 }
904 }
905 _player->SendSellError(SELL_ERR_CANT_FIND_ITEM, creature, itemguid, 0);
906 return;
907}
DBCStorage< DurabilityQualityEntry > sDurabilityQualityStore(DurabilityQualityfmt)
DBCStorage< DurabilityCostsEntry > sDurabilityCostsStore(DurabilityCostsfmt)
@ CREATURE_FLAG_EXTRA_NO_SELL_VENDOR
Definition: CreatureData.h:58
uint8 ItemSubClassToDurabilityMultiplierId(uint32 ItemClass, uint32 ItemSubClass)
Definition: ItemTemplate.h:557
@ SELL_ERR_UNK
Definition: Item.h:159
@ SELL_ERR_CANT_SELL_TO_THIS_MERCHANT
Definition: Item.h:161
@ SELL_ERR_CANT_FIND_ITEM
Definition: Item.h:155
@ SELL_ERR_CANT_SELL_ITEM
Definition: Item.h:156
@ ACHIEVEMENT_CRITERIA_TYPE_MONEY_FROM_VENDORS
Definition: DBCEnums.h:172
uint32 flags_extra
Definition: CreatureData.h:247
void RemoveFromUpdateQueueOf(Player *player)
Definition: Item.cpp:765
ObjectGuid GetOwnerGUID() const
Definition: Item.h:231
bool IsRefundable() const
Definition: Item.h:261
void AddItemToBuyBackSlot(Item *pItem, uint32 money)
Definition: PlayerStorage.cpp:3938
Definition: DBCStructure.h:877
uint32 multiplier[29]
Definition: DBCStructure.h:879
Definition: DBCStructure.h:883
float quality_mod
Definition: DBCStructure.h:885

References _player, ACHIEVEMENT_CRITERIA_TYPE_MONEY_FROM_VENDORS, Player::AddItemToBuyBackSlot(), ItemTemplate::Class, Item::CloneItem(), CONFIG_ITEMDELETE_VENDOR, CREATURE_FLAG_EXTRA_NO_SELL_VENDOR, EQUIP_ERR_TOO_MUCH_GOLD, CreatureTemplate::flags_extra, Item::GetBagSlot(), Item::GetCount(), Creature::GetCreatureTemplate(), Object::GetEntry(), Object::GetGUID(), Player::GetItemByGuid(), Player::GetLootGUID(), Player::GetMoney(), Player::GetNPCIfCanInteractWith(), Item::GetOwnerGUID(), GetPlayer(), Item::GetSlot(), Item::GetTemplate(), Object::GetUInt32Value(), Object::IsInWorld(), Item::IsNotEmptyBag(), Item::IsRefundable(), ITEM_CHANGED, ITEM_FIELD_DURABILITY, ITEM_FIELD_MAXDURABILITY, ItemTemplate::ItemLevel, Player::ItemRemovedQuestCheck(), ItemSubClassToDurabilityMultiplierId(), LOG_DEBUG, LOG_ERROR, MAX_MONEY_AMOUNT, Player::ModifyMoney(), DurabilityCostsEntry::multiplier, ItemTemplate::Quality, DurabilityQualityEntry::quality_mod, recoveryItem(), Unit::RemoveAurasByType(), Item::RemoveFromUpdateQueueOf(), Player::RemoveItem(), sDurabilityCostsStore, sDurabilityQualityStore, SELL_ERR_CANT_FIND_ITEM, SELL_ERR_CANT_FIND_VENDOR, SELL_ERR_CANT_SELL_ITEM, SELL_ERR_CANT_SELL_TO_THIS_MERCHANT, SELL_ERR_UNK, ItemTemplate::SellPrice, Player::SendEquipError(), Player::SendSellError(), Object::SendUpdateToPlayer(), Item::SetCount(), Item::SetState(), Object::SetUInt32Value(), SPELL_AURA_FEIGN_DEATH, sScriptMgr, ItemTemplate::SubClass, sWorld, ObjectGuid::ToString(), UNIT_NPC_FLAG_VENDOR, UNIT_STATE_DIED, Player::UpdateAchievementCriteria(), and Player::UpdateTitansGrip().

Referenced by OpcodeTable::Initialize().

◆ HandleSendMail()

void WorldSession::HandleSendMail ( WorldPacket recvData)

accountBound

64{
65 ObjectGuid mailbox;
66 uint64 unk3;
67 std::string receiver, subject, body;
68 uint32 unk1, unk2, money, COD;
69 uint8 unk4;
70
71 recvData >> mailbox;
72 recvData >> receiver;
73
74 recvData >> subject;
75
76 // prevent client crash
77 if (subject.find("| |") != std::string::npos || body.find("| |") != std::string::npos)
78 {
79 return;
80 }
81
82 recvData >> body;
83
84 recvData >> unk1; // stationery?
85 recvData >> unk2; // 0x00000000
86
87 uint8 items_count;
88 recvData >> items_count; // attached items count
89
90 if (items_count > MAX_MAIL_ITEMS) // client limit
91 {
93 recvData.rfinish(); // set to end to avoid warnings spam
94 return;
95 }
96
97 ObjectGuid itemGUIDs[MAX_MAIL_ITEMS];
98
99 for (uint8 i = 0; i < items_count; ++i)
100 {
101 recvData.read_skip<uint8>(); // item slot in mail, not used
102 recvData >> itemGUIDs[i];
103 }
104
105 recvData >> money >> COD; // money and cod
106 recvData >> unk3; // const 0
107 recvData >> unk4; // const 0
108
109 // packet read complete, now do check
110
111 if (!CanOpenMailBox(mailbox))
112 return;
113
114 if (receiver.empty())
115 return;
116
117 Player* player = _player;
118
119 if (player->GetLevel() < sWorld->getIntConfig(CONFIG_MAIL_LEVEL_REQ))
120 {
122 return;
123 }
124
125 ObjectGuid receiverGuid;
126 if (normalizePlayerName(receiver))
127 {
128 receiverGuid = sCharacterCache->GetCharacterGuidByName(receiver);
129 }
130
131 if (!receiverGuid)
132 {
133 LOG_DEBUG("network.opcode", "Player {} is sending mail to {} (GUID: not existed!) with subject {} and body {} includes {} items, {} copper and {} COD copper with unk1 = {}, unk2 = {}",
134 player->GetGUID().ToString(), receiver, subject, body, items_count, money, COD, unk1, unk2);
136 return;
137 }
138
139 LOG_DEBUG("network.opcode", "Player {} is sending mail to {} ({}) with subject {} and body {} includes {} items, {} copper and {} COD copper with unk1 = {}, unk2 = {}",
140 player->GetGUID().ToString(), receiver, receiverGuid.ToString(), subject, body, items_count, money, COD, unk1, unk2);
141
142 if (player->GetGUID() == receiverGuid)
143 {
145 return;
146 }
147
148 if (money && COD) // cannot send money in a COD mail
149 {
150 LOG_ERROR("network.opcode", "{} attempt to dupe money!!!.", receiver);
152 return;
153 }
154
155 uint32 cost = items_count ? 30 * items_count : 30; // price hardcoded in client
156
157 uint32 reqmoney = cost + money;
158
159 // Check for overflow
160 if (reqmoney < money)
161 {
163 return;
164 }
165
166 if (!player->HasEnoughMoney(reqmoney))
167 {
169 return;
170 }
171
172 Player* receive = ObjectAccessor::FindConnectedPlayer(receiverGuid);
173
174 uint32 rc_teamId = TEAM_NEUTRAL;
175 uint16 mails_count = 0; //do not allow to send to one player more than 100 mails
176
177 if (receive)
178 {
179 rc_teamId = receive->GetTeamId();
180 mails_count = receive->GetMailSize();
181 }
182 else
183 {
184 // xinef: get data from global storage
185 if (CharacterCacheEntry const* playerData = sCharacterCache->GetCharacterCacheByGuid(receiverGuid))
186 {
187 rc_teamId = Player::TeamIdForRace(playerData->Race);
188 mails_count = playerData->MailCount;
189 }
190 }
191 //do not allow to have more than 100 mails in mailbox.. mails count is in opcode uint8!!! - so max can be 255..
192 if (mails_count > 100)
193 {
195 return;
196 }
197 // test the receiver's Faction... or all items are account bound
198 // Xinef: check for boa items, not used currently
199 /*bool accountBound = items_count && !money && !COD ? true : false;
200 for (uint8 i = 0; i < items_count; ++i)
201 {
202 Item* item = player->GetItemByGuid(itemGUIDs[i]);
203 if (item)
204 {
205 ItemTemplate const* itemProto = item->GetTemplate();
206 if (!itemProto || !itemProto->HasFlag(ITEM_FLAG_IS_BOUND_TO_ACCOUNT))
207 {
208 accountBound = false;
209 break;
210 }
211 }
212 }*/
213
214 uint32 rc_account = receive ? receive->GetSession()->GetAccountId() : sCharacterCache->GetCharacterAccountIdByGuid(receiverGuid);
215
216 if ( GetAccountId() != rc_account && !sWorld->getBoolConfig(CONFIG_ALLOW_TWO_SIDE_INTERACTION_MAIL) && player->GetTeamId() != rc_teamId && AccountMgr::IsPlayerAccount(GetSecurity()))
217 {
219 return;
220 }
221
222 Item* items[MAX_MAIL_ITEMS];
223
224 for (uint8 i = 0; i < items_count; ++i)
225 {
226 if (!itemGUIDs[i])
227 {
229 return;
230 }
231
232 Item* item = player->GetItemByGuid(itemGUIDs[i]);
233
234 // prevent sending bag with items (cheat: can be placed in bag after adding equipped empty bag to mail)
235 if (!item)
236 {
238 return;
239 }
240
241 // handle empty bag before CanBeTraded, since that func already has that check
242 if (item->IsNotEmptyBag())
243 {
245 return;
246 }
247
248 if (!item->CanBeTraded(true))
249 {
251 return;
252 }
253
254 if (item->IsBoundAccountWide() && item->IsSoulBound() && GetAccountId() != rc_account)
255 {
257 return;
258 }
259
261 {
263 return;
264 }
265
266 if (COD && item->IsWrapped())
267 {
269 return;
270 }
271
272 if (!sScriptMgr->CanSendMail(player, receiverGuid, mailbox, subject, body, money, COD, item))
273 {
275 return;
276 }
277
278 items[i] = item;
279 }
280
281 if (!items_count && !sScriptMgr->CanSendMail(player, receiverGuid, mailbox, subject, body, money, COD, nullptr))
282 {
284 return;
285 }
286
287 player->SendMailResult(0, MAIL_SEND, MAIL_OK);
288
289 player->ModifyMoney(-int32(reqmoney));
291
292 bool needItemDelay = false;
293
294 MailDraft draft(subject, body);
295
296 CharacterDatabaseTransaction trans = CharacterDatabase.BeginTransaction();
297
298 if (items_count > 0 || money > 0)
299 {
300 if (items_count > 0)
301 {
302 for (uint8 i = 0; i < items_count; ++i)
303 {
304 Item* item = items[i];
305
306 item->SetNotRefundable(GetPlayer()); // makes the item no longer refundable
307 player->MoveItemFromInventory(items[i]->GetBagSlot(), item->GetSlot(), true);
308
309 item->DeleteFromInventoryDB(trans); // deletes item from character's inventory
310 if (item->GetState() == ITEM_UNCHANGED)
311 item->FSetState(ITEM_CHANGED); // pussywizard: so the item will be saved and owner will be updated in database
312 item->SetOwnerGUID(receiverGuid);
313 item->SaveToDB(trans); // recursive and not have transaction guard into self, item not in inventory and can be save standalone
314
315 draft.AddItem(item);
316 }
317
318 // if item send to character at another account, then apply item delivery delay
319 needItemDelay = GetAccountId() != rc_account;
320 }
321
322 if (money >= 10 * GOLD)
323 {
325 CharacterDatabase.Execute("INSERT INTO log_money VALUES({}, {}, \"{}\", \"{}\", {}, \"{}\", {}, \"{}\", NOW(), {})",
326 GetAccountId(), player->GetGUID().GetCounter(), player->GetName(), player->GetSession()->GetRemoteAddress(), rc_account, receiver, money, subject, 5);
327 }
328 }
329
330 // If theres is an item, there is a one hour delivery delay if sent to another account's character.
331 uint32 deliver_delay = needItemDelay ? sWorld->getIntConfig(CONFIG_MAIL_DELIVERY_DELAY) : 0;
332
333 // don't ask for COD if there are no items
334 if (items_count == 0)
335 COD = 0;
336
337 // will delete item or place to receiver mail list
338 draft
339 .AddMoney(money)
340 .AddCOD(COD)
341 .SendMailTo(trans, MailReceiver(receive, receiverGuid.GetCounter()), MailSender(player), body.empty() ? MAIL_CHECK_MASK_COPIED : MAIL_CHECK_MASK_HAS_BODY, deliver_delay);
342
343 player->SaveInventoryAndGoldToDB(trans);
344 CharacterDatabase.CommitTransaction(trans);
345}
@ CONFIG_MAIL_LEVEL_REQ
Definition: IWorld.h:298
@ CONFIG_MAIL_DELIVERY_DELAY
Definition: IWorld.h:262
@ CONFIG_ALLOW_TWO_SIDE_INTERACTION_MAIL
Definition: IWorld.h:79
@ LANG_MAIL_SENDER_REQ
Definition: Language.h:1158
@ EQUIP_ERR_MAIL_BOUND_ITEM
Definition: Item.h:119
@ EQUIP_ERR_CAN_ONLY_DO_WITH_EMPTY_BAGS
Definition: Item.h:78
@ EQUIP_ERR_ARTEFACTS_ONLY_FOR_OWN_CHARACTERS
Definition: Item.h:128
#define MAX_MAIL_ITEMS
Definition: Mail.h:34
@ MAIL_CHECK_MASK_HAS_BODY
Definition: Mail.h:52
@ MAIL_SEND
Definition: SharedDefines.h:3500
@ MAIL_ERR_NOT_YOUR_TEAM
Definition: SharedDefines.h:3515
@ MAIL_ERR_CANT_SEND_WRAPPED_COD
Definition: SharedDefines.h:3519
@ MAIL_ERR_RECIPIENT_CAP_REACHED
Definition: SharedDefines.h:3518
@ MAIL_ERR_RECIPIENT_NOT_FOUND
Definition: SharedDefines.h:3514
@ MAIL_ERR_TOO_MANY_ATTACHMENTS
Definition: SharedDefines.h:3521
@ MAIL_ERR_MAIL_ATTACHMENT_INVALID
Definition: SharedDefines.h:3522
@ MAIL_ERR_CANNOT_SEND_TO_SELF
Definition: SharedDefines.h:3512
@ ACHIEVEMENT_CRITERIA_TYPE_GOLD_SPENT_FOR_MAIL
Definition: DBCEnums.h:178
bool IsBoundAccountWide() const
Definition: Item.h:237
bool IsSoulBound() const
Definition: Item.h:236
ItemUpdateState GetState() const
Definition: Item.h:324
void SetNotRefundable(Player *owner, bool changestate=true, CharacterDatabaseTransaction *trans=nullptr)
Definition: Item.cpp:1201
void FSetState(ItemUpdateState state)
Definition: Item.h:330
void SetOwnerGUID(ObjectGuid guid)
Definition: Item.h:232
uint32 GetMailSize()
Definition: Player.h:1639

References _player, ACHIEVEMENT_CRITERIA_TYPE_GOLD_SPENT_FOR_MAIL, MailDraft::AddCOD(), MailDraft::AddItem(), MailDraft::AddMoney(), Item::CanBeTraded(), CanOpenMailBox(), CharacterDatabase, CleanStringForMysqlQuery(), CONFIG_ALLOW_TWO_SIDE_INTERACTION_MAIL, CONFIG_MAIL_DELIVERY_DELAY, CONFIG_MAIL_LEVEL_REQ, Item::DeleteFromInventoryDB(), EQUIP_ERR_ARTEFACTS_ONLY_FOR_OWN_CHARACTERS, EQUIP_ERR_CAN_ONLY_DO_WITH_EMPTY_BAGS, EQUIP_ERR_MAIL_BOUND_ITEM, ObjectAccessor::FindConnectedPlayer(), Item::FSetState(), GetAccountId(), ObjectGuid::GetCounter(), Object::GetGUID(), Player::GetItemByGuid(), Unit::GetLevel(), Player::GetMailSize(), WorldObject::GetName(), GetPlayer(), GetRemoteAddress(), GetSecurity(), Player::GetSession(), Item::GetSlot(), Item::GetState(), Player::GetTeamId(), Item::GetTemplate(), Object::GetUInt32Value(), GOLD, Player::HasEnoughMoney(), ItemTemplate::HasFlag(), Item::IsBoundAccountWide(), Item::IsNotEmptyBag(), AccountMgr::IsPlayerAccount(), Item::IsSoulBound(), Item::IsWrapped(), ITEM_CHANGED, ITEM_FIELD_DURATION, ITEM_FLAG_CONJURED, ITEM_UNCHANGED, LANG_MAIL_SENDER_REQ, LOG_DEBUG, LOG_ERROR, MAIL_CHECK_MASK_COPIED, MAIL_CHECK_MASK_HAS_BODY, MAIL_ERR_CANNOT_SEND_TO_SELF, MAIL_ERR_CANT_SEND_WRAPPED_COD, MAIL_ERR_EQUIP_ERROR, MAIL_ERR_INTERNAL_ERROR, MAIL_ERR_MAIL_ATTACHMENT_INVALID, MAIL_ERR_NOT_ENOUGH_MONEY, MAIL_ERR_NOT_YOUR_TEAM, MAIL_ERR_RECIPIENT_CAP_REACHED, MAIL_ERR_RECIPIENT_NOT_FOUND, MAIL_ERR_TOO_MANY_ATTACHMENTS, MAIL_OK, MAIL_SEND, MAX_MAIL_ITEMS, Player::ModifyMoney(), Player::MoveItemFromInventory(), normalizePlayerName(), ByteBuffer::read_skip(), ByteBuffer::rfinish(), Player::SaveInventoryAndGoldToDB(), Item::SaveToDB(), sCharacterCache, Player::SendMailResult(), MailDraft::SendMailTo(), ChatHandler::SendNotification(), Item::SetNotRefundable(), Item::SetOwnerGUID(), sScriptMgr, sWorld, TEAM_NEUTRAL, Player::TeamIdForRace(), ObjectGuid::ToString(), and Player::UpdateAchievementCriteria().

Referenced by OpcodeTable::Initialize().

◆ HandleSetActionBarToggles()

void WorldSession::HandleSetActionBarToggles ( WorldPacket recvData)
996{
997 uint8 ActionBar;
998
999 recv_data >> ActionBar;
1000
1001 if (!GetPlayer()) // ignore until not logged (check needed because STATUS_AUTHED)
1002 {
1003 if (ActionBar != 0)
1004 LOG_ERROR("network.opcode", "WorldSession::HandleSetActionBarToggles in not logged state with value: {}, ignored", uint32(ActionBar));
1005 return;
1006 }
1007
1008 GetPlayer()->SetByteValue(PLAYER_FIELD_BYTES, 2, ActionBar);
1009}
@ PLAYER_FIELD_BYTES
Definition: UpdateFields.h:368

References GetPlayer(), LOG_ERROR, PLAYER_FIELD_BYTES, and Object::SetByteValue().

Referenced by OpcodeTable::Initialize().

◆ HandleSetActionButtonOpcode()

void WorldSession::HandleSetActionButtonOpcode ( WorldPacket recvPacket)
937{
938 uint8 button;
939 uint32 packetData;
940 recv_data >> button >> packetData;
941
942 uint32 action = ACTION_BUTTON_ACTION(packetData);
943 uint8 type = ACTION_BUTTON_TYPE(packetData);
944
945 LOG_DEBUG("network.opcode", "BUTTON: {} ACTION: {} TYPE: {}", button, action, type);
946 if (!packetData)
947 {
948 LOG_DEBUG("network.opcode", "MISC: Remove action from button {}", button);
949 GetPlayer()->removeActionButton(button);
950 }
951 else
952 {
953 switch (type)
954 {
957 LOG_DEBUG("network.opcode", "MISC: Added Macro {} into button {}", action, button);
958 break;
960 LOG_DEBUG("network.opcode", "MISC: Added EquipmentSet {} into button {}", action, button);
961 break;
963 LOG_DEBUG("network.opcode", "MISC: Added Spell {} into button {}", action, button);
964 break;
966 LOG_DEBUG("network.opcode", "MISC: Added Item {} into button {}", action, button);
967 break;
968 default:
969 LOG_ERROR("network.opcode", "MISC: Unknown action button type {} for action {} into button {} for player {} ({})",
970 type, action, button, _player->GetName(), _player->GetGUID().ToString());
971 return;
972 }
973 GetPlayer()->addActionButton(button, action, type);
974 }
975}
@ ACTION_BUTTON_EQSET
Definition: Player.h:231
@ ACTION_BUTTON_MACRO
Definition: Player.h:232
@ ACTION_BUTTON_ITEM
Definition: Player.h:234
@ ACTION_BUTTON_CMACRO
Definition: Player.h:233
@ ACTION_BUTTON_SPELL
Definition: Player.h:229
#define ACTION_BUTTON_TYPE(X)
Definition: Player.h:249
#define ACTION_BUTTON_ACTION(X)
Definition: Player.h:248
ActionButton * addActionButton(uint8 button, uint32 action, uint8 type)
Definition: Player.cpp:5609
void removeActionButton(uint8 button)
Definition: Player.cpp:5624

References _player, ACTION_BUTTON_ACTION, ACTION_BUTTON_CMACRO, ACTION_BUTTON_EQSET, ACTION_BUTTON_ITEM, ACTION_BUTTON_MACRO, ACTION_BUTTON_SPELL, ACTION_BUTTON_TYPE, Player::addActionButton(), Object::GetGUID(), WorldObject::GetName(), GetPlayer(), LOG_DEBUG, LOG_ERROR, Player::removeActionButton(), and ObjectGuid::ToString().

Referenced by OpcodeTable::Initialize().

◆ HandleSetActiveMoverOpcode()

void WorldSession::HandleSetActiveMoverOpcode ( WorldPacket recvData)
718{
719 LOG_DEBUG("network", "WORLD: Recvd CMSG_SET_ACTIVE_MOVER");
720
721 ObjectGuid guid;
722 recvData >> guid;
723
724 if (GetPlayer()->IsInWorld() && _player->m_mover && _player->m_mover->IsInWorld())
725 {
726 if (_player->m_mover->GetGUID() != guid)
727 LOG_ERROR("network.opcode", "HandleSetActiveMoverOpcode: incorrect mover guid: mover is {} and should be {}",
728 guid.ToString(), _player->m_mover->GetGUID().ToString());
729 }
730}

References _player, Object::GetGUID(), GetPlayer(), Object::IsInWorld(), LOG_DEBUG, LOG_ERROR, Player::m_mover, and ObjectGuid::ToString().

Referenced by OpcodeTable::Initialize().

◆ HandleSetActiveVoiceChannel()

void WorldSession::HandleSetActiveVoiceChannel ( WorldPacket recvData)
38{
39 LOG_DEBUG("network", "WORLD: CMSG_SET_ACTIVE_VOICE_CHANNEL");
40 recvData.read_skip<uint32>();
41 recvData.read_skip<char*>();
42}

References LOG_DEBUG, and ByteBuffer::read_skip().

Referenced by OpcodeTable::Initialize().

◆ HandleSetAmmoOpcode()

void WorldSession::HandleSetAmmoOpcode ( WorldPacket recvPacket)
1197{
1198 if (!_player->IsAlive())
1199 {
1200 _player->SendEquipError(EQUIP_ERR_YOU_ARE_DEAD, nullptr, nullptr);
1201 return;
1202 }
1203
1204 LOG_DEBUG("network", "WORLD: CMSG_SET_AMMO");
1205 uint32 item;
1206
1207 recvData >> item;
1208
1209 if (item)
1210 {
1211 if (!_player->GetItemCount(item))
1212 {
1214 return;
1215 }
1216
1217 _player->SetAmmo(item);
1218 }
1219 else
1221}
uint32 GetItemCount(uint32 item, bool inBankAlso=false, Item *skipItem=nullptr) const
Definition: PlayerStorage.cpp:329
void RemoveAmmo()
Definition: PlayerStorage.cpp:2516
void SetAmmo(uint32 item)
Definition: PlayerStorage.cpp:2494

References _player, EQUIP_ERR_ITEM_NOT_FOUND, EQUIP_ERR_YOU_ARE_DEAD, Player::GetItemCount(), Unit::IsAlive(), LOG_DEBUG, Player::RemoveAmmo(), Player::SendEquipError(), and Player::SetAmmo().

Referenced by OpcodeTable::Initialize().

◆ HandleSetChannelWatch()

void WorldSession::HandleSetChannelWatch ( WorldPacket recvPacket)
309{
310 std::string channelName;
311 recvPacket >> channelName;
312
314
315 if (channelName.empty())
316 return;
317
319 if (Channel* channel = cMgr->GetChannel(channelName, nullptr, false))
320 channel->AddWatching(GetPlayer());
321}
void ClearChannelWatch()
Definition: Player.cpp:4999

References Player::ClearChannelWatch(), ChannelMgr::forTeam(), GetPlayer(), and GetTeamId().

Referenced by OpcodeTable::Initialize().

◆ HandleSetContactNotesOpcode()

void WorldSession::HandleSetContactNotesOpcode ( WorldPacket recvPacket)
148{
149 ObjectGuid guid;
150 std::string note;
151 recv_data >> guid >> note;
152 _player->GetSocial()->SetFriendNote(guid, note);
153}

References _player, Player::GetSocial(), and PlayerSocial::SetFriendNote().

Referenced by OpcodeTable::Initialize().

◆ HandleSetDungeonDifficultyOpcode()

void WorldSession::HandleSetDungeonDifficultyOpcode ( WorldPacket recvData)
1326{
1327 LOG_DEBUG("network", "MSG_SET_DUNGEON_DIFFICULTY");
1328
1329 uint32 mode;
1330 recv_data >> mode;
1331
1332 if (mode >= MAX_DUNGEON_DIFFICULTY)
1333 return;
1334
1335 if (Difficulty(mode) == _player->GetDungeonDifficulty())
1336 return;
1337
1338 Group* group = _player->GetGroup();
1339 if (group)
1340 {
1341 if (group->IsLeader(_player->GetGUID()))
1342 {
1343 for (GroupReference* itr = group->GetFirstMember(); itr != nullptr; itr = itr->next())
1344 {
1345 Player* groupGuy = itr->GetSource();
1346 if (!groupGuy)
1347 continue;
1348
1349 if (!groupGuy->IsInWorld())
1350 {
1351 _player->SendDungeonDifficulty(group != nullptr);
1352 return;
1353 }
1354
1355 if (groupGuy->GetGUID() == _player->GetGUID() ? groupGuy->GetMap()->IsDungeon() : groupGuy->GetMap()->IsNonRaidDungeon())
1356 {
1357 _player->SendDungeonDifficulty(group != nullptr);
1358 return;
1359 }
1360 }
1361
1363 group->SetDungeonDifficulty(Difficulty(mode));
1364 }
1365 }
1366 else
1367 {
1368 if (_player->FindMap() && _player->FindMap()->IsDungeon())
1369 {
1370 _player->SendDungeonDifficulty(group != nullptr);
1371 return;
1372 }
1375 }
1376}
@ INSTANCE_RESET_CHANGE_DIFFICULTY
Definition: Map.h:812
#define MAX_DUNGEON_DIFFICULTY
Definition: DBCEnums.h:281
void SetDungeonDifficulty(Difficulty dungeon_difficulty)
Definition: Player.h:1906
Difficulty GetDungeonDifficulty() const
Definition: Player.h:1903
void SetDungeonDifficulty(Difficulty difficulty)
Definition: Group.cpp:2073
void ResetInstances(uint8 method, bool isRaid, Player *leader)
Definition: Group.cpp:2115
bool IsNonRaidDungeon() const
Definition: Map.h:449

References _player, WorldObject::FindMap(), Player::GetDungeonDifficulty(), Group::GetFirstMember(), Player::GetGroup(), Object::GetGUID(), WorldObject::GetMap(), INSTANCE_RESET_CHANGE_DIFFICULTY, Map::IsDungeon(), Object::IsInWorld(), Group::IsLeader(), Map::IsNonRaidDungeon(), LOG_DEBUG, MAX_DUNGEON_DIFFICULTY, GroupReference::next(), Player::ResetInstances(), Group::ResetInstances(), Player::SendDungeonDifficulty(), Group::SetDungeonDifficulty(), and Player::SetDungeonDifficulty().

Referenced by OpcodeTable::Initialize().

◆ HandleSetFactionAtWar()

void WorldSession::HandleSetFactionAtWar ( WorldPacket recvData)
1260{
1261 uint32 repListID;
1262 uint8 flag;
1263
1264 recvData >> repListID;
1265 recvData >> flag;
1266
1267 GetPlayer()->GetReputationMgr().SetAtWar(repListID, flag);
1268}
void SetAtWar(RepListID repListID, bool on)
Definition: ReputationMgr.cpp:501

References GetPlayer(), Player::GetReputationMgr(), and ReputationMgr::SetAtWar().

Referenced by OpcodeTable::Initialize().

◆ HandleSetFactionCheat()

void WorldSession::HandleSetFactionCheat ( WorldPacket recvData)
1272{
1273 LOG_ERROR("network.opcode", "WORLD SESSION: HandleSetFactionCheat, not expected call, please report.");
1275}

References GetPlayer(), Player::GetReputationMgr(), LOG_ERROR, and ReputationMgr::SendStates().

Referenced by OpcodeTable::Initialize().

◆ HandleSetFactionInactiveOpcode()

void WorldSession::HandleSetFactionInactiveOpcode ( WorldPacket recvData)
1313{
1314 uint32 replistid;
1315 uint8 inactive;
1316 recvData >> replistid >> inactive;
1317
1318 _player->GetReputationMgr().SetInactive(replistid, inactive);
1319}
void SetInactive(RepListID repListID, bool on)
Definition: ReputationMgr.cpp:533

References _player, Player::GetReputationMgr(), and ReputationMgr::SetInactive().

Referenced by OpcodeTable::Initialize().

◆ HandleSetGuildBankTabText()

void WorldSession::HandleSetGuildBankTabText ( WorldPackets::Guild::GuildBankSetTabText packet)
397{
398 LOG_DEBUG("guild", "CMSG_SET_GUILD_BANK_TEXT [{}]: TabId: {}, Text: {}", GetPlayerInfo(), packet.Tab, packet.TabText);
399
400 if (Guild* guild = GetPlayer()->GetGuild())
401 guild->SetBankTabText(packet.Tab, packet.TabText);
402}
String< 500, Strings::NoHyperlinks > TabText
Definition: GuildPackets.h:585
uint8 Tab
Definition: GuildPackets.h:584

References GetPlayer(), GetPlayerInfo(), LOG_DEBUG, WorldPackets::Guild::GuildBankSetTabText::Tab, and WorldPackets::Guild::GuildBankSetTabText::TabText.

Referenced by OpcodeTable::Initialize().

◆ HandleSetPlayerDeclinedNames()

void WorldSession::HandleSetPlayerDeclinedNames ( WorldPacket recvData)
1423{
1424 // pussywizard:
1425 if (!sWorld->getBoolConfig(CONFIG_DECLINED_NAMES_USED))
1426 return;
1427
1428 ObjectGuid guid;
1429 recvData >> guid;
1430
1431 // not accept declined names for unsupported languages
1432 std::string name;
1433 if (!sCharacterCache->GetCharacterNameByGuid(guid, name))
1434 {
1436 return;
1437 }
1438
1439 std::wstring wname;
1440 if (!Utf8toWStr(name, wname))
1441 {
1443 return;
1444 }
1445
1446 if (!isCyrillicCharacter(wname[0])) // name already stored as only single alphabet using
1447 {
1449 return;
1450 }
1451
1452 std::string name2;
1453 DeclinedName declinedname;
1454
1455 recvData >> name2;
1456
1457 if (name2 != name) // character have different name
1458 {
1460 return;
1461 }
1462
1463 for (int i = 0; i < MAX_DECLINED_NAME_CASES; ++i)
1464 {
1465 recvData >> declinedname.name[i];
1466 if (!normalizePlayerName(declinedname.name[i]))
1467 {
1469 return;
1470 }
1471 }
1472
1473 if (!ObjectMgr::CheckDeclinedNames(wname, declinedname))
1474 {
1476 return;
1477 }
1478
1479 for (int i = 0; i < MAX_DECLINED_NAME_CASES; ++i)
1480 CharacterDatabase.EscapeString(declinedname.name[i]);
1481
1482 CharacterDatabaseTransaction trans = CharacterDatabase.BeginTransaction();
1483
1485 stmt->SetData(0, guid.GetCounter());
1486 trans->Append(stmt);
1487
1488 stmt = CharacterDatabase.GetPreparedStatement(CHAR_INS_CHAR_DECLINED_NAME);
1489 stmt->SetData(0, guid.GetCounter());
1490
1491 for (uint8 i = 0; i < 5; i++)
1492 stmt->SetData(i + 1, declinedname.name[i]);
1493
1494 trans->Append(stmt);
1495
1496 CharacterDatabase.CommitTransaction(trans);
1497
1499}
bool isCyrillicCharacter(wchar_t wchar)
Definition: Util.h:154
@ CHAR_INS_CHAR_DECLINED_NAME
Definition: CharacterDatabase.h:385
@ DECLINED_NAMES_RESULT_SUCCESS
Definition: WorldSession.h:216
@ DECLINED_NAMES_RESULT_ERROR
Definition: WorldSession.h:217
void SendSetPlayerDeclinedNamesResult(DeclinedNameResult result, ObjectGuid guid)
Definition: CharacterHandler.cpp:2622

References CHAR_DEL_CHAR_DECLINED_NAME, CHAR_INS_CHAR_DECLINED_NAME, CharacterDatabase, ObjectMgr::CheckDeclinedNames(), CONFIG_DECLINED_NAMES_USED, DECLINED_NAMES_RESULT_ERROR, DECLINED_NAMES_RESULT_SUCCESS, ObjectGuid::GetCounter(), isCyrillicCharacter(), MAX_DECLINED_NAME_CASES, DeclinedName::name, normalizePlayerName(), sCharacterCache, SendSetPlayerDeclinedNamesResult(), PreparedStatementBase::SetData(), sWorld, and Utf8toWStr().

Referenced by OpcodeTable::Initialize().

◆ HandleSetRaidDifficultyOpcode()

void WorldSession::HandleSetRaidDifficultyOpcode ( WorldPacket recvData)
1379{
1380 LOG_DEBUG("network", "MSG_SET_RAID_DIFFICULTY");
1381
1382 uint32 mode;
1383 recv_data >> mode;
1384
1385 if (mode >= MAX_RAID_DIFFICULTY)
1386 return;
1387
1388 if (Difficulty(mode) == _player->GetRaidDifficulty())
1389 return;
1390
1391 Group* group = _player->GetGroup();
1392 if (group)
1393 {
1394 if (group->IsLeader(_player->GetGUID()))
1395 {
1396 std::set<uint32> foundMaps;
1397 std::set<Map*> foundMapsPtr;
1398 Map* currMap = nullptr;
1399
1400 if (uint32 preventionTime = group->GetDifficultyChangePreventionTime())
1401 {
1402 switch (group->GetDifficultyChangePreventionReason())
1403 {
1405 ChatHandler(this).PSendSysMessage("Raid was in combat recently and may not change difficulty again for {} sec.", preventionTime);
1406 break;
1408 default:
1409 ChatHandler(this).PSendSysMessage("Raid difficulty has changed recently, and may not change again for {} sec.", preventionTime);
1410 break;
1411 }
1412
1413 _player->SendRaidDifficulty(group != nullptr);
1414 return;
1415 }
1416
1417 for (GroupReference* itr = group->GetFirstMember(); itr != nullptr; itr = itr->next())
1418 {
1419 Player* groupGuy = itr->GetSource();
1420 if (!groupGuy)
1421 continue;
1422
1423 if (!groupGuy->IsInWorld())
1424 {
1425 _player->SendRaidDifficulty(group != nullptr);
1426 return;
1427 }
1428
1429 if (IsSharedDifficultyMap(groupGuy->GetMap()->GetId()) && (uint32(mode % 2) == uint32(_player->GetRaidDifficulty() % 2)) && group->isRaidGroup())
1430 {
1431 if (!currMap)
1432 currMap = groupGuy->GetMap();
1433 foundMaps.insert(groupGuy->GetMap()->GetId());
1434 foundMapsPtr.insert(groupGuy->GetMap());
1435 if (foundMaps.size() > 1 || foundMapsPtr.size() > 1)
1436 {
1437 _player->SendRaidDifficulty(group != nullptr);
1438 return;
1439 }
1440
1441 if (!groupGuy->IsAlive() || groupGuy->IsInCombat() || groupGuy->GetVictim() || groupGuy->m_mover != groupGuy || groupGuy->IsNonMeleeSpellCast(true) || (!groupGuy->GetMotionMaster()->empty() && groupGuy->GetMotionMaster()->GetCurrentMovementGeneratorType() != IDLE_MOTION_TYPE)
1442 || !groupGuy->movespline->Finalized() || !groupGuy->GetMap()->ToInstanceMap() || !groupGuy->GetMap()->ToInstanceMap()->GetInstanceScript() || groupGuy->GetMap()->ToInstanceMap()->GetInstanceScript()->IsEncounterInProgress()
1443 || !groupGuy->Satisfy(sObjectMgr->GetAccessRequirement(groupGuy->GetMap()->GetId(), Difficulty(mode)), groupGuy->GetMap()->GetId(), false))
1444 {
1445 _player->SendRaidDifficulty(group != nullptr);
1446 return;
1447 }
1448 }
1449 else if (groupGuy->GetGUID() == _player->GetGUID() ? groupGuy->GetMap()->IsDungeon() : groupGuy->GetMap()->IsRaid())
1450 {
1451 _player->SendRaidDifficulty(group != nullptr);
1452 return;
1453 }
1454 }
1455
1456 Map* homeMap571 = sMapMgr->CreateMap(571, nullptr);
1457 Map* homeMap0 = sMapMgr->CreateMap(0, nullptr);
1458 ASSERT(homeMap0 && homeMap571);
1459
1460 std::map<Player*, Position> playerTeleport;
1461 // handle here all players in the instance that are not in the group
1462 if (currMap)
1463 for (Map::PlayerList::const_iterator itr = currMap->GetPlayers().begin(); itr != currMap->GetPlayers().end(); ++itr)
1464 if (Player* p = itr->GetSource())
1465 if (p->GetGroup() != group)
1466 {
1467 if (!p->IsInWorld() || !p->IsAlive() || p->IsInCombat() || p->GetVictim() || p->m_mover != p || p->IsNonMeleeSpellCast(true) || (!p->GetMotionMaster()->empty() && p->GetMotionMaster()->GetCurrentMovementGeneratorType() != IDLE_MOTION_TYPE)
1468 || !p->movespline->Finalized() || !p->GetMap()->ToInstanceMap() || !p->GetMap()->ToInstanceMap()->GetInstanceScript() || p->GetMap()->ToInstanceMap()->GetInstanceScript()->IsEncounterInProgress())
1469 {
1470 _player->SendRaidDifficulty(group != nullptr);
1471 return;
1472 }
1473 playerTeleport[p];
1474 }
1475 for (std::map<Player*, Position>::iterator itr = playerTeleport.begin(); itr != playerTeleport.end(); ++itr)
1476 {
1477 Player* p = itr->first;
1478 Map* oldMap = p->GetMap();
1479 oldMap->RemovePlayerFromMap(p, false);
1480 p->ResetMap();
1481 oldMap->AfterPlayerUnlinkFromMap();
1482 p->SetMap(homeMap0);
1483 p->Relocate(0.0f, 0.0f, 0.0f, 0.0f);
1484 if (!p->TeleportTo(571, 5790.20f, 2071.36f, 636.07f, 3.60f))
1485 p->GetSession()->KickPlayer("HandleSetRaidDifficultyOpcode 1");
1486 }
1487
1488 bool anyoneInside = false;
1489 playerTeleport.clear();
1490 for (GroupReference* itr = group->GetFirstMember(); itr != nullptr; itr = itr->next())
1491 {
1492 Player* groupGuy = itr->GetSource();
1493 if (!groupGuy)
1494 continue;
1495
1496 if (IsSharedDifficultyMap(groupGuy->GetMap()->GetId()))
1497 {
1498 anyoneInside = true;
1499
1500 float x, y, z, o;
1501 groupGuy->GetPosition(x, y, z, o);
1502 Map* oldMap = groupGuy->GetMap();
1503 oldMap->RemovePlayerFromMap(groupGuy, false);
1504 groupGuy->ResetMap();
1505 oldMap->AfterPlayerUnlinkFromMap();
1506 groupGuy->SetMap(homeMap571);
1507 groupGuy->Relocate(5790.20f, 2071.36f, 636.07f, 3.60f);
1508 Position dest = {x, y, z + 0.1f, o};
1509 playerTeleport[groupGuy] = dest;
1510 }
1511 }
1512
1513 if (!anyoneInside) // pussywizard: don't reset if changing ICC/RS difficulty while inside
1515 group->SetRaidDifficulty(Difficulty(mode));
1517
1518 for (std::map<Player*, Position>::iterator itr = playerTeleport.begin(); itr != playerTeleport.end(); ++itr)
1519 {
1520 itr->first->SetRaidDifficulty(Difficulty(mode)); // needed for teleport not to fail
1521 if (!itr->first->TeleportTo(*(foundMaps.begin()), itr->second.GetPositionX(), itr->second.GetPositionY(), itr->second.GetPositionZ(), itr->second.GetOrientation()))
1522 itr->first->GetSession()->KickPlayer("HandleSetRaidDifficultyOpcode 2");
1523 }
1524 }
1525 }
1526 else
1527 {
1528 if (_player->FindMap() && _player->FindMap()->IsDungeon())
1529 {
1530 _player->SendRaidDifficulty(group != nullptr);
1531 return;
1532 }
1535 }
1536}
@ DIFFICULTY_PREVENTION_CHANGE_RECENTLY_CHANGED
Definition: Group.h:134
@ DIFFICULTY_PREVENTION_CHANGE_BOSS_KILLED
Definition: Group.h:135
@ IDLE_MOTION_TYPE
Definition: MotionMaster.h:37
bool IsSharedDifficultyMap(uint32 mapid)
Definition: DBCStores.cpp:829
#define MAX_RAID_DIFFICULTY
Definition: DBCEnums.h:282
Definition: LinkedList.h:139
Difficulty GetRaidDifficulty() const
Definition: Player.h:1904
void SetRaidDifficulty(Difficulty raid_difficulty)
Definition: Player.h:1907
bool Satisfy(DungeonProgressionRequirements const *ar, uint32 target_map, bool report=false)
Definition: PlayerStorage.cpp:6707
void SendRaidDifficulty(bool IsInGroup, int32 forcedDifficulty=-1)
Definition: PlayerMisc.cpp:177
void SetRaidDifficulty(Difficulty difficulty)
Definition: Group.cpp:2094
DifficultyPreventionChangeType GetDifficultyChangePreventionReason() const
Definition: Group.h:319
void SetDifficultyChangePrevention(DifficultyPreventionChangeType type)
Definition: Group.cpp:2537
uint32 GetDifficultyChangePreventionTime() const
Definition: Group.cpp:2532
virtual bool IsEncounterInProgress() const
Definition: InstanceScript.cpp:122
bool IsRaid() const
Definition: Map.h:450
InstanceMap * ToInstanceMap()
Definition: Map.h:546
PlayerList const & GetPlayers() const
Definition: Map.h:486
InstanceScript * GetInstanceScript()
Definition: Map.h:831
iterator begin()
Definition: MapRefMgr.h:36
iterator end()
Definition: MapRefMgr.h:37
MovementGeneratorType GetCurrentMovementGeneratorType() const
Definition: MotionMaster.cpp:913
bool empty() const
Definition: MotionMaster.h:146

References _player, Map::AfterPlayerUnlinkFromMap(), ASSERT, MapRefMgr::begin(), DIFFICULTY_PREVENTION_CHANGE_BOSS_KILLED, DIFFICULTY_PREVENTION_CHANGE_RECENTLY_CHANGED, MotionMaster::empty(), MapRefMgr::end(), Movement::MoveSpline::Finalized(), WorldObject::FindMap(), MotionMaster::GetCurrentMovementGeneratorType(), Group::GetDifficultyChangePreventionReason(), Group::GetDifficultyChangePreventionTime(), Group::GetFirstMember(), Player::GetGroup(), Object::GetGUID(), Map::GetId(), InstanceMap::GetInstanceScript(), WorldObject::GetMap(), Unit::GetMotionMaster(), Map::GetPlayers(), Position::GetPosition(), Player::GetRaidDifficulty(), Player::GetSession(), Unit::GetVictim(), IDLE_MOTION_TYPE, INSTANCE_RESET_CHANGE_DIFFICULTY, Unit::IsAlive(), Map::IsDungeon(), InstanceScript::IsEncounterInProgress(), Unit::IsInCombat(), Object::IsInWorld(), Group::IsLeader(), Unit::IsNonMeleeSpellCast(), Map::IsRaid(), Group::isRaidGroup(), IsSharedDifficultyMap(), KickPlayer(), LOG_DEBUG, Player::m_mover, MAX_RAID_DIFFICULTY, Unit::movespline, GroupReference::next(), ChatHandler::PSendSysMessage(), Position::Relocate(), Map::RemovePlayerFromMap(), Player::ResetInstances(), Group::ResetInstances(), Player::ResetMap(), Player::Satisfy(), Player::SendRaidDifficulty(), Group::SetDifficultyChangePrevention(), Player::SetMap(), Group::SetRaidDifficulty(), Player::SetRaidDifficulty(), sMapMgr, sObjectMgr, Player::TeleportTo(), and Map::ToInstanceMap().

Referenced by OpcodeTable::Initialize().

◆ HandleSetSavedInstanceExtend()

void WorldSession::HandleSetSavedInstanceExtend ( WorldPacket recvData)
791{
792 uint32 mapId, difficulty;
793 uint8 toggleExtendOn;
794 recvData >> mapId >> difficulty >> toggleExtendOn;
795
796 MapEntry const* entry = sMapStore.LookupEntry(mapId);
797 if (!entry || !entry->IsRaid())
798 return;
799
800 InstancePlayerBind* instanceBind = sInstanceSaveMgr->PlayerGetBoundInstance(GetPlayer()->GetGUID(), mapId, Difficulty(difficulty));
801 if (!instanceBind || !instanceBind->perm || (bool)toggleExtendOn == instanceBind->extended)
802 return;
803
804 instanceBind->extended = (bool)toggleExtendOn;
805
806 // update in db
808 stmt->SetData(0, toggleExtendOn ? 1 : 0);
809 stmt->SetData(1, GetPlayer()->GetGUID().GetCounter());
810 stmt->SetData(2, instanceBind->save->GetInstanceId());
811 CharacterDatabase.Execute(stmt);
812
813 SendCalendarRaidLockoutUpdated(instanceBind->save, (bool)toggleExtendOn);
814}
@ CHAR_UPD_CHAR_INSTANCE_EXTENDED
Definition: CharacterDatabase.h:311
Definition: InstanceSaveMgr.h:39
InstanceSave * save
Definition: InstanceSaveMgr.h:40
bool extended
Definition: InstanceSaveMgr.h:42
bool perm
Definition: InstanceSaveMgr.h:41
void SendCalendarRaidLockoutUpdated(InstanceSave const *save, bool isExtended)
Definition: CalendarHandler.cpp:837

References CHAR_UPD_CHAR_INSTANCE_EXTENDED, CharacterDatabase, InstancePlayerBind::extended, ObjectGuid::GetCounter(), Object::GetGUID(), InstanceSave::GetInstanceId(), GetPlayer(), MapEntry::IsRaid(), InstancePlayerBind::perm, InstancePlayerBind::save, SendCalendarRaidLockoutUpdated(), PreparedStatementBase::SetData(), sInstanceSaveMgr, and sMapStore.

Referenced by OpcodeTable::Initialize().

◆ HandleSetSelectionOpcode()

void WorldSession::HandleSetSelectionOpcode ( WorldPacket recvPacket)
536{
537 ObjectGuid guid;
538 recv_data >> guid;
539
540 _player->SetSelection(guid);
541
542 // Change target of current autoshoot spell
543 if (guid)
544 {
545 if (Spell* autoReapeatSpell = _player->GetCurrentSpell(CURRENT_AUTOREPEAT_SPELL))
546 {
547 if (autoReapeatSpell->m_targets.GetUnitTargetGUID() != guid)
548 {
549 if (Unit* unit = ObjectAccessor::GetUnit(*_player, guid))
550 {
551 if (unit->IsAlive() && !_player->IsFriendlyTo(unit) && unit->isTargetableForAttack(true, _player))
552 {
553 autoReapeatSpell->m_targets.SetUnitTarget(unit);
554 }
555 }
556 }
557 }
558 }
559}
void SetSelection(ObjectGuid guid)
Used for serverside target changes, does not apply to players.
Definition: Player.cpp:11554
bool IsFriendlyTo(Unit const *unit) const
Definition: Unit.cpp:10210

References _player, CURRENT_AUTOREPEAT_SPELL, Unit::GetCurrentSpell(), ObjectAccessor::GetUnit(), Unit::IsFriendlyTo(), and Player::SetSelection().

Referenced by OpcodeTable::Initialize().

◆ HandleSetSheathedOpcode()

void WorldSession::HandleSetSheathedOpcode ( WorldPackets::Combat::SetSheathed packet)
74{
76 {
77 LOG_ERROR("network.opcode", "Unknown sheath state {} ??", packet.CurrentSheathState);
78 return;
79 }
80
82}
SheathState
Definition: UnitDefines.h:104
#define MAX_SHEATH_STATE
Definition: UnitDefines.h:110
void SetSheath(SheathState sheathed) override
Definition: PlayerStorage.cpp:99
uint32 CurrentSheathState
Definition: CombatPackets.h:35

References _player, WorldPackets::Combat::SetSheathed::CurrentSheathState, LOG_ERROR, MAX_SHEATH_STATE, and Player::SetSheath().

Referenced by OpcodeTable::Initialize().

◆ HandleSetTaxiBenchmarkOpcode()

void WorldSession::HandleSetTaxiBenchmarkOpcode ( WorldPacket recvData)
1600{
1601 uint8 mode;
1602 recv_data >> mode;
1603
1605
1606 LOG_DEBUG("network", "Client used \"/timetest {}\" command", mode);
1607}
@ PLAYER_FLAGS_TAXI_BENCHMARK
Definition: Player.h:491

References _player, LOG_DEBUG, PLAYER_FLAGS_TAXI_BENCHMARK, Player::RemovePlayerFlag(), and Player::SetPlayerFlag().

Referenced by OpcodeTable::Initialize().

◆ HandleSetTitleOpcode()

void WorldSession::HandleSetTitleOpcode ( WorldPacket recvData)
1294{
1295 LOG_DEBUG("network", "CMSG_SET_TITLE");
1296
1297 int32 title;
1298 recv_data >> title;
1299
1300 // -1 at none
1301 if (title > 0 && title < MAX_TITLE_INDEX)
1302 {
1303 if (!GetPlayer()->HasTitle(title))
1304 return;
1305 }
1306 else
1307 title = 0;
1308
1310}
@ PLAYER_CHOSEN_TITLE
Definition: UpdateFields.h:324
#define MAX_TITLE_INDEX
Definition: Player.h:554

References GetPlayer(), LOG_DEBUG, MAX_TITLE_INDEX, PLAYER_CHOSEN_TITLE, and Unit::SetUInt32Value().

Referenced by OpcodeTable::Initialize().

◆ HandleSetTradeGoldOpcode()

void WorldSession::HandleSetTradeGoldOpcode ( WorldPacket recvPacket)
661{
662 uint32 gold;
663 recvPacket >> gold;
664
665 TradeData* my_trade = _player->GetTradeData();
666 if (!my_trade)
667 return;
668
669 my_trade->SetMoney(gold);
670}
TradeData * GetTradeData() const
Definition: Player.h:1370
void SetMoney(uint32 money)
Definition: TradeData.cpp:93

References _player, Player::GetTradeData(), and TradeData::SetMoney().

Referenced by OpcodeTable::Initialize().

◆ HandleSetTradeItemOpcode()

void WorldSession::HandleSetTradeItemOpcode ( WorldPacket recvPacket)
673{
674 // send update
675 uint8 tradeSlot;
676 uint8 bag;
677 uint8 slot;
678
679 recvPacket >> tradeSlot;
680 recvPacket >> bag;
681 recvPacket >> slot;
682
683 TradeData* my_trade = _player->GetTradeData();
684 if (!my_trade)
685 return;
686
687 // invalid slot number
688 if (tradeSlot >= TRADE_SLOT_COUNT)
689 {
691 return;
692 }
693
694 // check cheating, can't fail with correct client operations
695 Item* item = _player->GetItemByPos(bag, slot);
696 if (!item || (tradeSlot != TRADE_SLOT_NONTRADED && !item->CanBeTraded(false, true)))
697 {
699 return;
700 }
701
702 ObjectGuid iGUID = item->GetGUID();
703
704 // prevent place single item into many trade slots using cheating and client bugs
705 if (my_trade->HasItem(iGUID))
706 {
707 // cheating attempt
709 return;
710 }
711
712 // PlayerScript Hook for checking traded items if we want to filter them in a custom module
713 if (!sScriptMgr->CanSetTradeItem(_player, item, tradeSlot))
714 {
715 // Do not send TRADE_STATUS_TRADE_CANCELED because it will cause double display of "Transaction canceled" notification
716 // On the trade initiator screen
718 return;
719 }
720
721 my_trade->SetItem(TradeSlots(tradeSlot), item);
722}
bool HasItem(ObjectGuid itemGuid) const
Definition: TradeData.cpp:31

References _player, Item::CanBeTraded(), Object::GetGUID(), Player::GetItemByPos(), Player::GetTradeData(), TradeData::HasItem(), SendTradeStatus(), TradeData::SetItem(), sScriptMgr, TRADE_SLOT_COUNT, TRADE_SLOT_NONTRADED, TRADE_STATUS_CLOSE_WINDOW, and TRADE_STATUS_TRADE_CANCELED.

Referenced by OpcodeTable::Initialize().

◆ HandleSetWatchedFactionOpcode()

void WorldSession::HandleSetWatchedFactionOpcode ( WorldPacket recvData)
1306{
1307 uint32 fact;
1308 recvData >> fact;
1310}
@ PLAYER_FIELD_WATCHED_FACTION_INDEX
Definition: UpdateFields.h:379

References GetPlayer(), PLAYER_FIELD_WATCHED_FACTION_INDEX, and Unit::SetUInt32Value().

Referenced by OpcodeTable::Initialize().

◆ HandleShowingCloakOpcode()

◆ HandleShowingHelmOpcode()

◆ HandleSocketClosed()

bool WorldSession::HandleSocketClosed ( )
526{
527 if (m_Socket && !m_Socket->IsOpen() && !IsKicked() && GetPlayer() && !PlayerLogout() && GetPlayer()->m_taxi.empty() && GetPlayer()->IsInWorld() && !World::IsStopped())
528 {
529 m_Socket = nullptr;
530 GetPlayer()->TradeCancel(false);
531 return true;
532 }
533
534 return false;
535}
bool PlayerLogout() const
Definition: WorldSession.h:338
bool IsKicked() const
Definition: WorldSession.h:1069
static bool IsStopped()
Definition: World.h:254

References GetPlayer(), IsKicked(), World::IsStopped(), m_Socket, PlayerLogout(), and Player::TradeCancel().

Referenced by World::AddSession_(), and World::UpdateSessions().

◆ HandleSocketOpcode()

void WorldSession::HandleSocketOpcode ( WorldPacket recvData)
1402{
1403 LOG_DEBUG("network", "WORLD: CMSG_SOCKET_GEMS");
1404
1405 ObjectGuid item_guid;
1406 ObjectGuid gem_guids[MAX_GEM_SOCKETS];
1407
1408 recvData >> item_guid;
1409 if (!item_guid)
1410 return;
1411
1412 for (int i = 0; i < MAX_GEM_SOCKETS; ++i)
1413 recvData >> gem_guids[i];
1414
1415 //cheat -> tried to socket same gem multiple times
1416 if ((gem_guids[0] && (gem_guids[0] == gem_guids[1] || gem_guids[0] == gem_guids[2])) ||
1417 (gem_guids[1] && (gem_guids[1] == gem_guids[2])))
1418 return;
1419
1420 Item* itemTarget = _player->GetItemByGuid(item_guid);
1421 if (!itemTarget) //missing item to socket
1422 return;
1423
1424 ItemTemplate const* itemProto = itemTarget->GetTemplate();
1425 if (!itemProto)
1426 return;
1427
1428 //this slot is excepted when applying / removing meta gem bonus
1429 uint8 slot = itemTarget->IsEquipped() ? itemTarget->GetSlot() : uint8(NULL_SLOT);
1430
1431 Item* Gems[MAX_GEM_SOCKETS];
1432 for (int i = 0; i < MAX_GEM_SOCKETS; ++i)
1433 Gems[i] = gem_guids[i] ? _player->GetItemByGuid(gem_guids[i]) : nullptr;
1434
1435 GemPropertiesEntry const* GemProps[MAX_GEM_SOCKETS];
1436 for (int i = 0; i < MAX_GEM_SOCKETS; ++i) //get geminfo from dbc storage
1437 GemProps[i] = (Gems[i]) ? sGemPropertiesStore.LookupEntry(Gems[i]->GetTemplate()->GemProperties) : nullptr;
1438
1439 // Find first prismatic socket
1440 int32 firstPrismatic = 0;
1441 while (firstPrismatic < MAX_GEM_SOCKETS && itemProto->Socket[firstPrismatic].Color)
1442 ++firstPrismatic;
1443
1444 for (int i = 0; i < MAX_GEM_SOCKETS; ++i) //check for hack maybe
1445 {
1446 if (!GemProps[i])
1447 continue;
1448
1449 // tried to put gem in socket where no socket exists (take care about prismatic sockets)
1450 if (!itemProto->Socket[i].Color)
1451 {
1452 // no prismatic socket
1454 return;
1455
1456 if (i != firstPrismatic)
1457 return;
1458 }
1459
1460 // tried to put normal gem in meta socket
1461 if (itemProto->Socket[i].Color == SOCKET_COLOR_META && GemProps[i]->color != SOCKET_COLOR_META)
1462 return;
1463
1464 // tried to put meta gem in normal socket
1465 if (itemProto->Socket[i].Color != SOCKET_COLOR_META && GemProps[i]->color == SOCKET_COLOR_META)
1466 return;
1467 }
1468
1469 uint32 GemEnchants[MAX_GEM_SOCKETS];
1470 uint32 OldEnchants[MAX_GEM_SOCKETS];
1471 for (int i = 0; i < MAX_GEM_SOCKETS; ++i) //get new and old enchantments
1472 {
1473 GemEnchants[i] = (GemProps[i]) ? GemProps[i]->spellitemenchantement : 0;
1474 OldEnchants[i] = itemTarget->GetEnchantmentId(EnchantmentSlot(SOCK_ENCHANTMENT_SLOT + i));
1475 }
1476
1477 // check unique-equipped conditions
1478 for (int i = 0; i < MAX_GEM_SOCKETS; ++i)
1479 {
1480 if (!Gems[i])
1481 continue;
1482
1483 // continue check for case when attempt add 2 similar unique equipped gems in one item.
1484 ItemTemplate const* iGemProto = Gems[i]->GetTemplate();
1485
1486 // unique item (for new and already placed bit removed enchantments
1487 if (iGemProto->HasFlag(ITEM_FLAG_UNIQUE_EQUIPPABLE))
1488 {
1489 for (int j = 0; j < MAX_GEM_SOCKETS; ++j)
1490 {
1491 if (i == j) // skip self
1492 continue;
1493
1494 if (Gems[j])
1495 {
1496 if (iGemProto->ItemId == Gems[j]->GetEntry())
1497 {
1499 return;
1500 }
1501 }
1502 else if (OldEnchants[j])
1503 {
1504 if (SpellItemEnchantmentEntry const* enchantEntry = sSpellItemEnchantmentStore.LookupEntry(OldEnchants[j]))
1505 {
1506 if (iGemProto->ItemId == enchantEntry->GemID)
1507 {
1509 return;
1510 }
1511 }
1512 }
1513 }
1514 }
1515
1516 // unique limit type item
1517 int32 limit_newcount = 0;
1518 if (iGemProto->ItemLimitCategory)
1519 {
1520 if (ItemLimitCategoryEntry const* limitEntry = sItemLimitCategoryStore.LookupEntry(iGemProto->ItemLimitCategory))
1521 {
1522 // NOTE: limitEntry->mode is not checked because if item has limit then it is applied in equip case
1523 for (int j = 0; j < MAX_GEM_SOCKETS; ++j)
1524 {
1525 if (Gems[j])
1526 {
1527 // new gem
1528 if (iGemProto->ItemLimitCategory == Gems[j]->GetTemplate()->ItemLimitCategory)
1529 ++limit_newcount;
1530 }
1531 else if (OldEnchants[j])
1532 {
1533 // existing gem
1534 if (SpellItemEnchantmentEntry const* enchantEntry = sSpellItemEnchantmentStore.LookupEntry(OldEnchants[j]))
1535 if (ItemTemplate const* jProto = sObjectMgr->GetItemTemplate(enchantEntry->GemID))
1536 if (iGemProto->ItemLimitCategory == jProto->ItemLimitCategory)
1537 ++limit_newcount;
1538 }
1539 }
1540
1541 if (limit_newcount > 0 && uint32(limit_newcount) > limitEntry->maxCount)
1542 {
1544 return;
1545 }
1546 }
1547 }
1548
1549 // for equipped item check all equipment for duplicate equipped gems
1550 if (itemTarget->IsEquipped())
1551 {
1552 if (InventoryResult res = _player->CanEquipUniqueItem(Gems[i], slot, std::max(limit_newcount, 0)))
1553 {
1554 _player->SendEquipError(res, itemTarget, nullptr);
1555 return;
1556 }
1557 }
1558 }
1559
1560 bool SocketBonusActivated = itemTarget->GemsFitSockets(); //save state of socketbonus
1561 _player->ToggleMetaGemsActive(slot, false); //turn off all metagems (except for the target item)
1562
1563 //if a meta gem is being equipped, all information has to be written to the item before testing if the conditions for the gem are met
1564
1565 //remove ALL enchants
1566 for (uint32 enchant_slot = SOCK_ENCHANTMENT_SLOT; enchant_slot < SOCK_ENCHANTMENT_SLOT + MAX_GEM_SOCKETS; ++enchant_slot)
1567 _player->ApplyEnchantment(itemTarget, EnchantmentSlot(enchant_slot), false);
1568
1569 for (int i = 0; i < MAX_GEM_SOCKETS; ++i)
1570 {
1571 if (GemEnchants[i])
1572 {
1573 itemTarget->SetEnchantment(EnchantmentSlot(SOCK_ENCHANTMENT_SLOT + i), GemEnchants[i], 0, 0, _player->GetGUID());
1574 if (Item* guidItem = _player->GetItemByGuid(gem_guids[i]))
1575 _player->DestroyItem(guidItem->GetBagSlot(), guidItem->GetSlot(), true);
1576 }
1577 }
1578
1579 for (uint32 enchant_slot = SOCK_ENCHANTMENT_SLOT; enchant_slot < SOCK_ENCHANTMENT_SLOT + MAX_GEM_SOCKETS; ++enchant_slot)
1580 _player->ApplyEnchantment(itemTarget, EnchantmentSlot(enchant_slot), true);
1581
1582 bool SocketBonusToBeActivated = itemTarget->GemsFitSockets();//current socketbonus state
1583 if (SocketBonusActivated ^ SocketBonusToBeActivated) //if there was a change...
1584 {
1585 _player->ApplyEnchantment(itemTarget, BONUS_ENCHANTMENT_SLOT, false);
1586 itemTarget->SetEnchantment(BONUS_ENCHANTMENT_SLOT, (SocketBonusToBeActivated ? itemTarget->GetTemplate()->socketBonus : 0), 0, 0, _player->GetGUID());
1588 //it is not displayed, client has an inbuilt system to determine if the bonus is activated
1589 }
1590
1591 _player->ToggleMetaGemsActive(slot, true); //turn on all metagems (except for target item)
1592
1593 _player->RemoveTradeableItem(itemTarget);
1594 itemTarget->ClearSoulboundTradeable(_player); // clear tradeable flag
1595
1596 itemTarget->SendUpdateSockets();
1597}
DBCStorage< SpellItemEnchantmentEntry > sSpellItemEnchantmentStore(SpellItemEnchantmentfmt)
DBCStorage< ItemLimitCategoryEntry > sItemLimitCategoryStore(ItemLimitCategoryEntryfmt)
DBCStorage< GemPropertiesEntry > sGemPropertiesStore(GemPropertiesEntryfmt)
@ ITEM_FLAG_UNIQUE_EQUIPPABLE
Definition: ItemTemplate.h:166
@ SOCKET_COLOR_META
Definition: ItemTemplate.h:246
@ EQUIP_ERR_ITEM_UNIQUE_EQUIPPABLE_SOCKETED
Definition: Item.h:122
#define MAX_GEM_SOCKETS
Definition: Item.h:188
@ PRISMATIC_ENCHANTMENT_SLOT
Definition: Item.h:175
@ SOCK_ENCHANTMENT_SLOT
Definition: Item.h:171
@ BONUS_ENCHANTMENT_SLOT
Definition: Item.h:174
bool GemsFitSockets() const
Definition: Item.cpp:971
void SendUpdateSockets()
Definition: Item.cpp:1063
void ClearSoulboundTradeable(Player *currentOwner)
Definition: Item.cpp:1265
void SetEnchantment(EnchantmentSlot slot, uint32 id, uint32 duration, uint32 charges, ObjectGuid caster=ObjectGuid::Empty)
Definition: Item.cpp:921
void ToggleMetaGemsActive(uint8 exceptslot, bool apply)
Definition: Player.cpp:11248
InventoryResult CanEquipUniqueItem(Item *pItem, uint8 except_slot=NULL_SLOT, uint32 limit_count=1) const
Definition: Player.cpp:13787
void RemoveTradeableItem(Item *item)
Definition: PlayerStorage.cpp:4141
Definition: DBCStructure.h:1013
Definition: DBCStructure.h:1195
Definition: DBCStructure.h:1840
Definition: Socket.h:52

References _player, Player::ApplyEnchantment(), BONUS_ENCHANTMENT_SLOT, Player::CanEquipUniqueItem(), Item::ClearSoulboundTradeable(), _Socket::Color, GemPropertiesEntry::color, Player::DestroyItem(), EQUIP_ERR_ITEM_UNIQUE_EQUIPPABLE_SOCKETED, Item::GemsFitSockets(), Item::GetEnchantmentId(), Object::GetEntry(), Object::GetGUID(), Player::GetItemByGuid(), Item::GetSlot(), Item::GetTemplate(), ItemTemplate::HasFlag(), Item::IsEquipped(), ITEM_FLAG_UNIQUE_EQUIPPABLE, ItemTemplate::ItemId, ItemTemplate::ItemLimitCategory, LOG_DEBUG, MAX_GEM_SOCKETS, NULL_SLOT, PRISMATIC_ENCHANTMENT_SLOT, Player::RemoveTradeableItem(), Player::SendEquipError(), Item::SendUpdateSockets(), Item::SetEnchantment(), sGemPropertiesStore, sItemLimitCategoryStore, sObjectMgr, SOCK_ENCHANTMENT_SLOT, ItemTemplate::Socket, SOCKET_COLOR_META, ItemTemplate::socketBonus, sSpellItemEnchantmentStore, and Player::ToggleMetaGemsActive().

Referenced by OpcodeTable::Initialize().

◆ HandleSpellClick()

void WorldSession::HandleSpellClick ( WorldPacket recvData)
Todo:
: Unit::SetCharmedBy: 28782 is not in world but 0 is trying to charm it! -> crash
647{
648 ObjectGuid guid;
649 recvData >> guid;
650
651 // this will get something not in world. crash
653
654 if (!unit)
655 return;
656
658 if (!unit->IsInWorld())
659 return;
660
662}
bool HandleSpellClick(Unit *clicker, int8 seatId=-1)
Definition: Unit.cpp:19519

References _player, ObjectAccessor::GetCreatureOrPetOrVehicle(), Unit::HandleSpellClick(), and Object::IsInWorld().

Referenced by OpcodeTable::Initialize().

◆ HandleSpiritHealerActivateOpcode()

void WorldSession::HandleSpiritHealerActivateOpcode ( WorldPacket recvPacket)
366{
367 LOG_DEBUG("network", "WORLD: CMSG_SPIRIT_HEALER_ACTIVATE");
368
369 ObjectGuid guid;
370
371 recvData >> guid;
372
374 if (!unit)
375 {
376 LOG_DEBUG("network", "WORLD: HandleSpiritHealerActivateOpcode - Unit ({}) not found or you can not interact with him.", guid.ToString());
377 return;
378 }
379
380 // remove fake death
381 if (GetPlayer()->HasUnitState(UNIT_STATE_DIED))
383
385}
@ UNIT_NPC_FLAG_SPIRITHEALER
Definition: UnitDefines.h:308
void SendSpiritResurrect()
Definition: NPCHandler.cpp:387

References Player::GetNPCIfCanInteractWith(), GetPlayer(), LOG_DEBUG, Unit::RemoveAurasByType(), SendSpiritResurrect(), SPELL_AURA_FEIGN_DEATH, ObjectGuid::ToString(), UNIT_NPC_FLAG_SPIRITHEALER, and UNIT_STATE_DIED.

Referenced by OpcodeTable::Initialize().

◆ HandleSplitItemOpcode()

void WorldSession::HandleSplitItemOpcode ( WorldPacket recvPacket)
34{
35 //LOG_DEBUG("network.opcode", "WORLD: CMSG_SPLIT_ITEM");
36 uint8 srcbag, srcslot, dstbag, dstslot;
37 uint32 count;
38
39 recvData >> srcbag >> srcslot >> dstbag >> dstslot >> count;
40
41 uint16 src = ((srcbag << 8) | srcslot);
42 uint16 dst = ((dstbag << 8) | dstslot);
43
44 if (src == dst)
45 return;
46
47 if (count == 0)
48 return; //check count - if zero it's fake packet
49
50 if (!_player->IsValidPos(srcbag, srcslot, true))
51 {
53 return;
54 }
55
56 if (!_player->IsValidPos(dstbag, dstslot, false)) // can be autostore pos
57 {
59 return;
60 }
61
62 _player->SplitItem(src, dst, count);
63}
void SplitItem(uint16 src, uint16 dst, uint32 count)
Definition: PlayerStorage.cpp:3423

References _player, EQUIP_ERR_ITEM_DOESNT_GO_TO_SLOT, EQUIP_ERR_ITEM_NOT_FOUND, Player::IsValidPos(), Player::SendEquipError(), and Player::SplitItem().

Referenced by OpcodeTable::Initialize().

◆ HandleStablePet()

void WorldSession::HandleStablePet ( WorldPacket recvPacket)
551{
552 LOG_DEBUG("network", "WORLD: Recv CMSG_STABLE_PET");
553 ObjectGuid npcGUID;
554
555 recvData >> npcGUID;
556
557 if (!GetPlayer()->IsAlive())
558 {
560 return;
561 }
562
563 if (!CheckStableMaster(npcGUID))
564 {
566 return;
567 }
568
569 // remove fake death
570 if (GetPlayer()->HasUnitState(UNIT_STATE_DIED))
572
573 PetStable* petStable = GetPlayer()->GetPetStable();
574 if (!petStable)
575 return;
576
577 Pet* pet = _player->GetPet();
578
579 // can't place in stable dead pet
580 if ((pet && (!pet->IsAlive() || pet->getPetType() != HUNTER_PET))
581 || (!pet && (petStable->UnslottedPets.size() != 1 || !petStable->UnslottedPets[0].Health || petStable->UnslottedPets[0].Type != HUNTER_PET)))
582 {
584 return;
585 }
586
587 for (uint32 freeSlot = 0; freeSlot < petStable->MaxStabledPets; ++freeSlot)
588 {
589 if (!petStable->StabledPets[freeSlot])
590 {
591 if (pet)
592 {
593 // stable summoned pet
595 std::swap(petStable->StabledPets[freeSlot], petStable->CurrentPet);
597 return;
598 }
599
601 stmt->SetData(0, PetSaveMode(PET_SAVE_FIRST_STABLE_SLOT + freeSlot));
602 stmt->SetData(1, _player->GetGUID().GetCounter());
603 stmt->SetData(2, petStable->UnslottedPets[0].PetNumber);
604 CharacterDatabase.Execute(stmt);
605
606 // stable unsummoned pet
607 petStable->StabledPets[freeSlot] = std::move(petStable->UnslottedPets.back());
608 petStable->UnslottedPets.pop_back();
610 return;
611 }
612 }
613
614 // not free stable slot
616}
@ STABLE_SUCCESS_STABLE
Definition: NPCHandler.cpp:40
PetSaveMode
Definition: PetDefines.h:40
@ PET_SAVE_FIRST_STABLE_SLOT
Definition: PetDefines.h:43
@ CHAR_UPD_CHAR_PET_SLOT_BY_ID
Definition: CharacterDatabase.h:483
std::array< Optional< PetInfo >, MAX_PET_STABLES > StabledPets
Definition: PetDefines.h:226
std::vector< PetInfo > UnslottedPets
Definition: PetDefines.h:228

References _player, CHAR_UPD_CHAR_PET_SLOT_BY_ID, CharacterDatabase, CheckStableMaster(), PetStable::CurrentPet, ObjectGuid::GetCounter(), Object::GetGUID(), Player::GetPet(), Player::GetPetStable(), Pet::getPetType(), GetPlayer(), HUNTER_PET, Unit::IsAlive(), LOG_DEBUG, PetStable::MaxStabledPets, PET_SAVE_FIRST_STABLE_SLOT, Unit::RemoveAurasByType(), Player::RemovePet(), SendStableResult(), PreparedStatementBase::SetData(), SPELL_AURA_FEIGN_DEATH, STABLE_ERR_STABLE, STABLE_SUCCESS_STABLE, PetStable::StabledPets, UNIT_STATE_DIED, and PetStable::UnslottedPets.

Referenced by OpcodeTable::Initialize().

◆ HandleStableRevivePet()

void WorldSession::HandleStableRevivePet ( WorldPacket recvPacket)
767{
768 LOG_DEBUG("network", "HandleStableRevivePet: Not implemented");
769}

References LOG_DEBUG.

Referenced by OpcodeTable::Initialize().

◆ HandleStableSwapPet()

void WorldSession::HandleStableSwapPet ( WorldPacket recvPacket)
772{
773 LOG_DEBUG("network", "WORLD: Recv CMSG_STABLE_SWAP_PET.");
774 ObjectGuid npcGUID;
775 uint32 petId;
776
777 recvData >> npcGUID >> petId;
778
779 if (!CheckStableMaster(npcGUID))
780 {
782 return;
783 }
784
785 // remove fake death
786 if (GetPlayer()->HasUnitState(UNIT_STATE_DIED))
788
789 PetStable* petStable = GetPlayer()->GetPetStable();
790 if (!petStable)
791 {
793 return;
794 }
795
796 // Find swapped pet slot in stable
797 auto stabledPet = std::find_if(petStable->StabledPets.begin(), petStable->StabledPets.end(), [petId](Optional<PetStable::PetInfo> const& pet)
798 {
799 return pet && pet->PetNumber == petId;
800 });
801
802 if (stabledPet == petStable->StabledPets.end())
803 {
805 return;
806 }
807
808 CreatureTemplate const* creatureInfo = sObjectMgr->GetCreatureTemplate((*stabledPet)->CreatureId);
809 if (!creatureInfo || !creatureInfo->IsTameable(_player->CanTameExoticPets()))
810 {
811 // if problem in exotic pet
812 if (creatureInfo && creatureInfo->IsTameable(true))
814 else
816 return;
817 }
818
819 Pet* oldPet = _player->GetPet();
820 if (oldPet)
821 {
822 if (!oldPet->IsAlive() || !oldPet->IsHunterPet())
823 {
825 return;
826 }
827
828 _player->RemovePet(oldPet, PetSaveMode(PET_SAVE_FIRST_STABLE_SLOT + std::distance(petStable->StabledPets.begin(), stabledPet)));
829 }
830 else if (petStable->UnslottedPets.size() == 1)
831 {
832 if (petStable->CurrentPet || !petStable->UnslottedPets[0].Health || petStable->UnslottedPets[0].Type != HUNTER_PET)
833 {
835 return;
836 }
837
839 stmt->SetData(0, PetSaveMode(PET_SAVE_FIRST_STABLE_SLOT + std::distance(petStable->StabledPets.begin(), stabledPet)));
840 stmt->SetData(1, _player->GetGUID().GetCounter());
841 stmt->SetData(2, petStable->UnslottedPets[0].PetNumber);
842 CharacterDatabase.Execute(stmt);
843
844 // move unsummoned pet into CurrentPet slot so that it gets moved into stable slot later
845 petStable->CurrentPet = std::move(petStable->UnslottedPets.back());
846 petStable->UnslottedPets.pop_back();
847 }
848 else if (petStable->CurrentPet || !petStable->UnslottedPets.empty())
849 {
851 return;
852 }
853
854 // summon unstabled pet
855 Pet* newPet = new Pet(_player, HUNTER_PET);
856 if (!newPet->LoadPetFromDB(_player, 0, petId, false))
857 {
858 delete newPet;
860
861 petStable->UnslottedPets.push_back(std::move(*petStable->CurrentPet));
862 petStable->CurrentPet.reset();
863
864 // update current pet slot in db immediately to maintain slot consistency, dismissed pet was already saved
867 stmt->SetData(1, _player->GetGUID().GetCounter());
868 stmt->SetData(2, petId);
869 CharacterDatabase.Execute(stmt);
870 }
871 else
872 {
873 // update current pet slot in db immediately to maintain slot consistency, dismissed pet was already saved
876 stmt->SetData(1, _player->GetGUID().GetCounter());
877 stmt->SetData(2, petId);
878 CharacterDatabase.Execute(stmt);
879
881 }
882}
@ STABLE_ERR_EXOTIC
Definition: NPCHandler.cpp:43
@ STABLE_SUCCESS_UNSTABLE
Definition: NPCHandler.cpp:41
bool IsTameable(bool exotic) const
Definition: CreatureData.h:275
bool LoadPetFromDB(Player *owner, uint32 petEntry, uint32 petnumber, bool current, uint32 healthPct=0, bool fullMana=false)
Definition: Pet.cpp:215
bool CanTameExoticPets() const
Definition: Player.h:2171
bool IsHunterPet() const
Definition: Unit.h:711

References _player, Player::CanTameExoticPets(), CHAR_UPD_CHAR_PET_SLOT_BY_ID, CharacterDatabase, CheckStableMaster(), PetStable::CurrentPet, ObjectGuid::GetCounter(), Object::GetGUID(), Player::GetPet(), Player::GetPetStable(), GetPlayer(), HUNTER_PET, Unit::IsAlive(), Unit::IsHunterPet(), CreatureTemplate::IsTameable(), Pet::LoadPetFromDB(), LOG_DEBUG, PET_SAVE_AS_CURRENT, PET_SAVE_FIRST_STABLE_SLOT, PET_SAVE_NOT_IN_SLOT, Unit::RemoveAurasByType(), Player::RemovePet(), SendStableResult(), PreparedStatementBase::SetData(), sObjectMgr, SPELL_AURA_FEIGN_DEATH, STABLE_ERR_EXOTIC, STABLE_ERR_STABLE, STABLE_SUCCESS_UNSTABLE, PetStable::StabledPets, UNIT_STATE_DIED, and PetStable::UnslottedPets.

Referenced by OpcodeTable::Initialize().

◆ HandleStandStateChangeOpcode()

void WorldSession::HandleStandStateChangeOpcode ( WorldPacket recvPacket)
562{
563 uint32 animstate;
564 recv_data >> animstate;
565
566 switch (animstate)
567 {
572 break;
573 default:
574 return;
575 }
576
577 _player->SetStandState(animstate);
578}
@ UNIT_STAND_STATE_SLEEP
Definition: UnitDefines.h:35
@ UNIT_STAND_STATE_KNEEL
Definition: UnitDefines.h:40

References _player, Unit::SetStandState(), UNIT_STAND_STATE_KNEEL, UNIT_STAND_STATE_SIT, UNIT_STAND_STATE_SLEEP, and UNIT_STAND_STATE_STAND.

Referenced by OpcodeTable::Initialize().

◆ HandleSummonResponseOpcode()

void WorldSession::HandleSummonResponseOpcode ( WorldPacket recvData)
829{
830 if (!_player->IsAlive() || _player->IsInCombat())
831 return;
832
833 ObjectGuid summoner_guid;
834 bool agree;
835 recvData >> summoner_guid;
836 recvData >> agree;
837
838 if (agree && _player->IsSummonAsSpectator())
839 {
840 ChatHandler chc(this);
841 if (Player* summoner = ObjectAccessor::FindPlayer(summoner_guid))
842 ArenaSpectator::HandleSpectatorSpectateCommand(&chc, summoner->GetName().c_str());
843 else
844 chc.PSendSysMessage("Requested player not found.");
845
846 agree = false;
847 }
849 _player->SummonIfPossible(agree, summoner_guid);
850}
AC_GAME_API bool HandleSpectatorSpectateCommand(ChatHandler *handler, std::string const &name)
Definition: ArenaSpectator.cpp:29
void SetSummonAsSpectator(bool on)
Definition: Player.h:1099
void SummonIfPossible(bool agree, ObjectGuid summoner_guid)
Definition: Player.cpp:12417
bool IsSummonAsSpectator() const
Definition: Player.cpp:16332

References _player, ObjectAccessor::FindPlayer(), ArenaSpectator::HandleSpectatorSpectateCommand(), Unit::IsAlive(), Unit::IsInCombat(), Player::IsSummonAsSpectator(), ChatHandler::PSendSysMessage(), Player::SetSummonAsSpectator(), and Player::SummonIfPossible().

Referenced by OpcodeTable::Initialize().

◆ HandleSwapInvItemOpcode()

void WorldSession::HandleSwapInvItemOpcode ( WorldPacket recvPacket)
66{
67 //LOG_DEBUG("network.opcode", "WORLD: CMSG_SWAP_INV_ITEM");
68 uint8 srcslot, dstslot;
69
70 recvData >> dstslot >> srcslot;
71
72 // prevent attempt swap same item to current position generated by client at special checting sequence
73 if (srcslot == dstslot)
74 return;
75
76 if (!_player->IsValidPos(INVENTORY_SLOT_BAG_0, srcslot, true))
77 {
79 return;
80 }
81
82 if (!_player->IsValidPos(INVENTORY_SLOT_BAG_0, dstslot, true))
83 {
85 return;
86 }
87
89 {
90 //LOG_DEBUG("network", "WORLD: HandleSwapInvItemOpcode - Unit ({}) not found or you can't interact with him.", m_currentBankerGUID.ToString());
91 return;
92 }
93
95 {
96 //LOG_DEBUG("network", "WORLD: HandleSwapInvItemOpcode - Unit ({}) not found or you can't interact with him.", m_currentBankerGUID.ToString());
97 return;
98 }
99
100 uint16 src = ((INVENTORY_SLOT_BAG_0 << 8) | srcslot);
101 uint16 dst = ((INVENTORY_SLOT_BAG_0 << 8) | dstslot);
102
103 _player->SwapItem(src, dst);
104}

References _player, CanUseBank(), EQUIP_ERR_ITEM_DOESNT_GO_TO_SLOT, EQUIP_ERR_ITEM_NOT_FOUND, INVENTORY_SLOT_BAG_0, Player::IsBankPos(), Player::IsValidPos(), Player::SendEquipError(), and Player::SwapItem().

Referenced by OpcodeTable::Initialize().

◆ HandleSwapItem()

void WorldSession::HandleSwapItem ( WorldPacket recvPacket)
126{
127 //LOG_DEBUG("network.opcode", "WORLD: CMSG_SWAP_ITEM");
128 uint8 dstbag, dstslot, srcbag, srcslot;
129
130 recvData >> dstbag >> dstslot >> srcbag >> srcslot;
131
132 uint16 src = ((srcbag << 8) | srcslot);
133 uint16 dst = ((dstbag << 8) | dstslot);
134
135 // prevent attempt swap same item to current position generated by client at special checting sequence
136 if (src == dst)
137 return;
138
139 if (!_player->IsValidPos(srcbag, srcslot, true))
140 {
142 return;
143 }
144
145 if (!_player->IsValidPos(dstbag, dstslot, true))
146 {
148 return;
149 }
150
151 if (_player->IsBankPos(srcbag, srcslot) && !CanUseBank())
152 {
153 //LOG_DEBUG("network", "WORLD: HandleSwapItem - Unit ({}) not found or you can't interact with him.", m_currentBankerGUID.ToString());
154 return;
155 }
156
157 if (_player->IsBankPos(dstbag, dstslot) && !CanUseBank())
158 {
159 //LOG_DEBUG("network", "WORLD: HandleSwapItem - Unit ({}) not found or you can't interact with him.", m_currentBankerGUID.ToString());
160 return;
161 }
162
163 _player->SwapItem(src, dst);
164}

References _player, CanUseBank(), EQUIP_ERR_ITEM_DOESNT_GO_TO_SLOT, EQUIP_ERR_ITEM_NOT_FOUND, Player::IsBankPos(), Player::IsValidPos(), Player::SendEquipError(), and Player::SwapItem().

Referenced by OpcodeTable::Initialize().

◆ HandleTabardVendorActivateOpcode()

void WorldSession::HandleTabardVendorActivateOpcode ( WorldPacket recvPacket)
47{
48 ObjectGuid guid;
49 recvData >> guid;
50
52 if (!unit)
53 {
54 LOG_DEBUG("network", "WORLD: HandleTabardVendorActivateOpcode - Unit ({}) not found or you can not interact with him.", guid.ToString());
55 return;
56 }
57
58 // remove fake death
59 if (GetPlayer()->HasUnitState(UNIT_STATE_DIED))
61
63}
void SendTabardVendorActivate(ObjectGuid guid)
Definition: NPCHandler.cpp:65

References Player::GetNPCIfCanInteractWith(), GetPlayer(), LOG_DEBUG, Unit::RemoveAurasByType(), SendTabardVendorActivate(), SPELL_AURA_FEIGN_DEATH, ObjectGuid::ToString(), UNIT_NPC_FLAG_TABARDDESIGNER, and UNIT_STATE_DIED.

Referenced by OpcodeTable::Initialize().

◆ HandleTalentWipeConfirmOpcode()

void WorldSession::HandleTalentWipeConfirmOpcode ( WorldPacket recvPacket)
59{
60 LOG_DEBUG("network", "MSG_TALENT_WIPE_CONFIRM");
61 ObjectGuid guid;
62 recvData >> guid;
63
65 if (!unit)
66 {
67 LOG_DEBUG("network", "WORLD: HandleTalentWipeConfirmOpcode - Unit ({}) not found or you can't interact with him.", guid.ToString());
68 return;
69 }
70
72 return;
73
74 // remove fake death
75 if (GetPlayer()->HasUnitState(UNIT_STATE_DIED))
77
78 if (!(_player->resetTalents()))
79 {
80 WorldPacket data(MSG_TALENT_WIPE_CONFIRM, 8 + 4); //you have not any talent
81 data << uint64(0);
82 data << uint32(0);
83 SendPacket(&data);
84 return;
85 }
86
88 unit->CastSpell(_player, 14867, true); //spell: "Untalent Visual Effect"
89}
@ UNIT_NPC_FLAG_TRAINER
Definition: UnitDefines.h:298
@ MSG_TALENT_WIPE_CONFIRM
Definition: Opcodes.h:712
bool isCanTrainingAndResetTalentsOf(Player *player) const
Definition: Creature.cpp:1257

References _player, Unit::CastSpell(), Player::GetNPCIfCanInteractWith(), GetPlayer(), Creature::isCanTrainingAndResetTalentsOf(), LOG_DEBUG, MSG_TALENT_WIPE_CONFIRM, Unit::RemoveAurasByType(), Player::resetTalents(), SendPacket(), Player::SendTalentsInfoData(), SPELL_AURA_FEIGN_DEATH, ObjectGuid::ToString(), UNIT_NPC_FLAG_TRAINER, and UNIT_STATE_DIED.

Referenced by OpcodeTable::Initialize().

◆ HandleTaxiNodeStatusQueryOpcode()

void WorldSession::HandleTaxiNodeStatusQueryOpcode ( WorldPacket recvPacket)
28{
29 ObjectGuid guid;
30
31 recvData >> guid;
32 SendTaxiStatus(guid);
33}
void SendTaxiStatus(ObjectGuid guid)
Definition: TaxiHandler.cpp:35

References SendTaxiStatus().

Referenced by OpcodeTable::Initialize().

◆ HandleTaxiQueryAvailableNodes()

void WorldSession::HandleTaxiQueryAvailableNodes ( WorldPacket recvPacket)
60{
61 ObjectGuid guid;
62 recvData >> guid;
63
64 // cheating checks
66 if (!unit)
67 {
68 LOG_DEBUG("network", "WORLD: HandleTaxiQueryAvailableNodes - Unit ({}) not found or you can't interact with him.", guid.ToString());
69 return;
70 }
71
72 // remove fake death
73 if (GetPlayer()->HasUnitState(UNIT_STATE_DIED))
75
76 // unknown taxi node case
77 if (SendLearnNewTaxiNode(unit))
78 return;
79
80 // known taxi node case
81 SendTaxiMenu(unit);
82}
bool SendLearnNewTaxiNode(Creature *unit)
Definition: TaxiHandler.cpp:127
void SendTaxiMenu(Creature *unit)
Definition: TaxiHandler.cpp:84

References Player::GetNPCIfCanInteractWith(), GetPlayer(), LOG_DEBUG, Unit::RemoveAurasByType(), SendLearnNewTaxiNode(), SendTaxiMenu(), SPELL_AURA_FEIGN_DEATH, ObjectGuid::ToString(), UNIT_NPC_FLAG_FLIGHTMASTER, and UNIT_STATE_DIED.

Referenced by OpcodeTable::Initialize().

◆ HandleTeleportTimeout()

void WorldSession::HandleTeleportTimeout ( bool  updateInSessions)
543{
544 // pussywizard: handle teleport ack timeout
545 if (m_Socket && m_Socket->IsOpen() && GetPlayer() && GetPlayer()->IsBeingTeleported())
546 {
547 time_t currTime = GameTime::GetGameTime().count();
548 if (updateInSessions) // session update from World::UpdateSessions
549 {
550 if (GetPlayer()->IsBeingTeleportedFar() && GetPlayer()->GetSemaphoreTeleportFar() + sWorld->getIntConfig(CONFIG_TELEPORT_TIMEOUT_FAR) < currTime)
551 while (GetPlayer() && GetPlayer()->IsBeingTeleportedFar())
553 }
554 else // session update from Map::Update
555 {
556 if (GetPlayer()->IsBeingTeleportedNear() && GetPlayer()->GetSemaphoreTeleportNear() + sWorld->getIntConfig(CONFIG_TELEPORT_TIMEOUT_NEAR) < currTime)
557 while (GetPlayer() && GetPlayer()->IsInWorld() && GetPlayer()->IsBeingTeleportedNear())
558 {
559 Player* plMover = GetPlayer()->m_mover->ToPlayer();
560 if (!plMover)
561 break;
563 pkt << plMover->GetPackGUID();
564 pkt << uint32(0); // flags
565 pkt << uint32(0); // time
567 }
568 }
569 }
570}
@ CONFIG_TELEPORT_TIMEOUT_FAR
Definition: IWorld.h:343
@ CONFIG_TELEPORT_TIMEOUT_NEAR
Definition: IWorld.h:342
void HandleMoveTeleportAck(WorldPacket &recvPacket)
Definition: MovementHandler.cpp:266

References CONFIG_TELEPORT_TIMEOUT_FAR, CONFIG_TELEPORT_TIMEOUT_NEAR, GameTime::GetGameTime(), Object::GetPackGUID(), GetPlayer(), HandleMoveTeleportAck(), HandleMoveWorldportAck(), Player::m_mover, m_Socket, MSG_MOVE_TELEPORT_ACK, sWorld, and Object::ToPlayer().

Referenced by Update().

◆ HandleTextEmoteOpcode()

void WorldSession::HandleTextEmoteOpcode ( WorldPacket recvPacket)
729{
730 if (!GetPlayer()->IsAlive())
731 return;
732
734
735 if (!GetPlayer()->CanSpeak())
736 {
737 std::string timeStr = secsToTimeString(m_muteTime - GameTime::GetGameTime().count());
739 return;
740 }
741
742 if (GetPlayer()->IsSpectator())
743 return;
744
745 uint32 text_emote, emoteNum;
746 ObjectGuid guid;
747
748 recvData >> text_emote;
749 recvData >> emoteNum;
750 recvData >> guid;
751
752 sScriptMgr->OnPlayerTextEmote(GetPlayer(), text_emote, emoteNum, guid);
753
754 EmotesTextEntry const* em = sEmotesTextStore.LookupEntry(text_emote);
755 if (!em)
756 return;
757
758 uint32 emote_anim = em->textid;
759
760 switch (emote_anim)
761 {
763 case EMOTE_STATE_SIT:
766 break;
769 break;
770 default:
771 // Only allow text-emotes for "dead" entities (feign death included)
772 if (GetPlayer()->HasUnitState(UNIT_STATE_DIED))
773 break;
774 GetPlayer()->HandleEmoteCommand(emote_anim);
775 break;
776 }
777
778 Unit* unit = ObjectAccessor::GetUnit(*_player, guid);
779
780 CellCoord p = Acore::ComputeCellCoord(GetPlayer()->GetPositionX(), GetPlayer()->GetPositionY());
781
782 Cell cell(p);
783 cell.SetNoCreate();
784
785 Acore::EmoteChatBuilder emote_builder(*GetPlayer(), text_emote, emoteNum, unit);
789 cell.Visit(p, message, *GetPlayer()->GetMap(), *GetPlayer(), sWorld->getFloatConfig(CONFIG_LISTEN_RANGE_TEXTEMOTE));
790
792
793 //Send scripted event call
794 if (unit && unit->IsCreature() && ((Creature*)unit)->AI())
795 ((Creature*)unit)->AI()->ReceiveEmote(GetPlayer(), text_emote);
796}
DBCStorage< EmotesTextEntry > sEmotesTextStore(EmotesTextEntryfmt)
@ CONFIG_LISTEN_RANGE_TEXTEMOTE
Definition: IWorld.h:195
@ EMOTE_STATE_SLEEP
Definition: SharedDefines.h:1904
@ EMOTE_STATE_SIT
Definition: SharedDefines.h:1905
@ EMOTE_STATE_KNEEL
Definition: SharedDefines.h:1943
@ EMOTE_STATE_DANCE
Definition: SharedDefines.h:1902
@ ACHIEVEMENT_CRITERIA_TYPE_DO_EMOTE
Definition: DBCEnums.h:168
Definition: TypeContainer.h:101
Definition: TypeContainerVisitor.h:84
Definition: GridNotifiers.h:592
Definition: GridNotifiers.h:1707
Definition: ChatHandler.cpp:699
Definition: DBCStructure.h:900
uint32 textid
Definition: DBCStructure.h:902

References _player, ACHIEVEMENT_CRITERIA_TYPE_DO_EMOTE, Acore::ComputeCellCoord(), CONFIG_LISTEN_RANGE_TEXTEMOTE, EMOTE_ONESHOT_NONE, EMOTE_STATE_DANCE, EMOTE_STATE_KNEEL, EMOTE_STATE_SIT, EMOTE_STATE_SLEEP, GameTime::GetGameTime(), GetPlayer(), ObjectAccessor::GetUnit(), Unit::HandleEmoteCommand(), Object::IsCreature(), LANG_WAIT_BEFORE_SPEAKING, m_muteTime, Player::ChatFloodThrottle::REGULAR, secsToTimeString(), sEmotesTextStore, ChatHandler::SendNotification(), Cell::SetNoCreate(), Unit::SetUInt32Value(), sScriptMgr, sWorld, EmotesTextEntry::textid, UNIT_NPC_EMOTESTATE, UNIT_STATE_DIED, Player::UpdateAchievementCriteria(), Player::UpdateSpeakTime(), and Cell::Visit().

Referenced by OpcodeTable::Initialize().

◆ HandleTimeSyncResp()

void WorldSession::HandleTimeSyncResp ( WorldPacket recvData)
885{
886 LOG_DEBUG("network", "CMSG_TIME_SYNC_RESP");
887
888 uint32 counter, clientTimestamp;
889 recvData >> counter >> clientTimestamp;
890
891 if (_pendingTimeSyncRequests.count(counter) == 0)
892 return;
893
894 uint32 serverTimeAtSent = _pendingTimeSyncRequests.at(counter);
895 _pendingTimeSyncRequests.erase(counter);
896
897 // time it took for the request to travel to the client, for the client to process it and reply and for response to travel back to the server.
898 // we are going to make 2 assumptions:
899 // 1) we assume that the request processing time equals 0.
900 // 2) we assume that the packet took as much time to travel from server to client than it took to travel from client to server.
901 uint32 roundTripDuration = getMSTimeDiff(serverTimeAtSent, recvData.GetReceivedTime());
902 uint32 lagDelay = roundTripDuration / 2;
903
904 // clockDelta = serverTime - clientTime
905 // where
906 // serverTime: time that was displayed on the clock of the SERVER at the moment when the client processed the SMSG_TIME_SYNC_REQUEST packet.
907 // clientTime: time that was displayed on the clock of the CLIENT at the moment when the client processed the SMSG_TIME_SYNC_REQUEST packet.
908
909 // Once clockDelta has been computed, we can compute the time of an event on server clock when we know the time of that same event on the client clock,
910 // using the following relation:
911 // serverTime = clockDelta + clientTime
912
913 int64 clockDelta = (int64)serverTimeAtSent + (int64)lagDelay - (int64)clientTimestamp;
914 _timeSyncClockDeltaQueue.put(std::pair<int64, uint32>(clockDelta, roundTripDuration));
916}
void put(T item)
Definition: CircularBuffer.h:27
TimePoint GetReceivedTime() const
Definition: WorldPacket.h:79
void ComputeNewClockDelta()
Definition: MovementHandler.cpp:918

References _pendingTimeSyncRequests, _timeSyncClockDeltaQueue, ComputeNewClockDelta(), getMSTimeDiff(), WorldPacket::GetReceivedTime(), LOG_DEBUG, and CircularBuffer< T >::put().

Referenced by OpcodeTable::Initialize().

◆ HandleTogglePvP()

void WorldSession::HandleTogglePvP ( WorldPacket recvPacket)
502{
503 // this opcode can be used in two ways: Either set explicit new status or toggle old status
504 if (recv_data.size() == 1)
505 {
506 bool newPvPStatus;
507 recv_data >> newPvPStatus;
509 }
510 else
512
513 if (GetPlayer()->HasPlayerFlag(PLAYER_FLAGS_IN_PVP))
514 GetPlayer()->UpdatePvP(true, true);
515 else if (!GetPlayer()->pvpInfo.IsHostile && GetPlayer()->IsPvP()) // pussywizard: in pvp mode, but doesn't want to be and not in hostile territory, so start timer
516 GetPlayer()->UpdatePvP(true, false);
517
518 //if (OutdoorPvP* pvp = _player->GetOutdoorPvP())
519 // pvp->HandlePlayerActivityChanged(_player);
520}
@ PLAYER_FLAGS
Definition: UpdateFields.h:178
void ApplyModFlag(uint16 index, uint32 flag, bool apply)
Definition: Object.cpp:899
void ToggleFlag(uint16 index, uint32 flag)
Definition: Object.cpp:877

References Object::ApplyModFlag(), GetPlayer(), PLAYER_FLAGS, PLAYER_FLAGS_IN_PVP, ByteBuffer::size(), Object::ToggleFlag(), and Player::UpdatePvP().

Referenced by OpcodeTable::Initialize().

◆ HandleTotemDestroyed()

void WorldSession::HandleTotemDestroyed ( WorldPackets::Totem::TotemDestroyed totemDestroyed)
610{
611 // ignore for remote control state
612 if (_player->m_mover != _player)
613 return;
614
615 uint8 slotId = totemDestroyed.Slot;
616 slotId += SUMMON_SLOT_TOTEM;
617
618 if (slotId >= MAX_TOTEM_SLOT)
619 return;
620
621 if (!_player->m_SummonSlot[slotId])
622 return;
623
624 Creature* totem = GetPlayer()->GetMap()->GetCreature(_player->m_SummonSlot[slotId]);
625 // Don't unsummon sentry totem
626 if (totem && totem->IsTotem())
627 totem->ToTotem()->UnSummon();
628}
#define SUMMON_SLOT_TOTEM
Definition: Unit.h:597
#define MAX_TOTEM_SLOT
Definition: Unit.h:598
void UnSummon(uint32 msTime=0) override
Definition: Totem.cpp:122
Totem * ToTotem()
Definition: Unit.h:1729
bool IsTotem() const
Definition: Unit.h:712
ObjectGuid m_SummonSlot[MAX_SUMMON_SLOT]
Definition: Unit.h:1797
uint8 Slot
Definition: TotemPackets.h:35

References _player, Map::GetCreature(), WorldObject::GetMap(), GetPlayer(), Unit::IsTotem(), Player::m_mover, Unit::m_SummonSlot, MAX_TOTEM_SLOT, WorldPackets::Totem::TotemDestroyed::Slot, SUMMON_SLOT_TOTEM, Unit::ToTotem(), and Totem::UnSummon().

Referenced by OpcodeTable::Initialize().

◆ HandleTrainerBuySpellOpcode()

void WorldSession::HandleTrainerBuySpellOpcode ( WorldPacket recvPacket)
213{
214 ObjectGuid guid;
215 uint32 spellId = 0;
216
217 recvData >> guid >> spellId;
218
220 if (!unit)
221 {
222 LOG_DEBUG("network", "WORLD: HandleTrainerBuySpellOpcode - Unit ({}) not found or you can not interact with him.", guid.ToString());
223 return;
224 }
225
226 // remove fake death
227 if (GetPlayer()->HasUnitState(UNIT_STATE_DIED))
229
230 // check present spell in trainer spell list
231 TrainerSpellData const* trainer_spells = unit->GetTrainerSpells();
232 if (!trainer_spells)
233 return;
234
235 // not found, cheat?
236 TrainerSpell const* trainer_spell = trainer_spells->Find(spellId);
237 if (!trainer_spell)
238 return;
239
240 if (trainer_spell->reqSpell && !_player->HasSpell(trainer_spell->reqSpell))
241 {
242 return;
243 }
244
245 // can't be learn, cheat? Or double learn with lags...
246 if (_player->GetTrainerSpellState(trainer_spell) != TRAINER_SPELL_GREEN)
247 return;
248
249 // apply reputation discount
250 uint32 nSpellCost = uint32(std::floor(trainer_spell->spellCost * _player->GetReputationPriceDiscount(unit)));
251
252 // check money requirement
253 if (!_player->HasEnoughMoney(nSpellCost))
254 return;
255
256 _player->ModifyMoney(-int32(nSpellCost));
257
258 unit->SendPlaySpellVisual(179); // 53 SpellCastDirected
259 unit->SendPlaySpellImpact(_player->GetGUID(), 362); // 113 EmoteSalute
260
261 // learn explicitly or cast explicitly
262 if (trainer_spell->IsCastable())
263 _player->CastSpell(_player, trainer_spell->spell, true);
264 else
265 _player->learnSpell(spellId);
266
268 data << guid;
269 data << uint32(spellId); // should be same as in packet from client
270 SendPacket(&data);
271}
@ TRAINER_SPELL_GREEN
Definition: Player.h:213
@ SMSG_TRAINER_BUY_SUCCEEDED
Definition: Opcodes.h:465
TrainerSpellData const * GetTrainerSpells() const
Definition: Creature.cpp:3131
Definition: CreatureData.h:508
bool IsCastable() const
Definition: CreatureData.h:524
uint32 reqSpell
Definition: CreatureData.h:521
uint32 spellCost
Definition: CreatureData.h:516
uint32 spell
Definition: CreatureData.h:515
Definition: CreatureData.h:530
TrainerSpell const * Find(uint32 spell_id) const
Definition: Creature.cpp:83
void learnSpell(uint32 spellId, bool temporary=false, bool learnFromSkill=false)
Definition: Player.cpp:3271
TrainerSpellState GetTrainerSpellState(TrainerSpell const *trainer_spell) const
Definition: Player.cpp:3877
void SendPlaySpellVisual(uint32 id)
Definition: Unit.cpp:18876
void SendPlaySpellImpact(ObjectGuid guid, uint32 id)
Definition: Unit.cpp:18884

References _player, Unit::CastSpell(), TrainerSpellData::Find(), Object::GetGUID(), Player::GetNPCIfCanInteractWith(), GetPlayer(), Player::GetReputationPriceDiscount(), Creature::GetTrainerSpells(), Player::GetTrainerSpellState(), Player::HasEnoughMoney(), Player::HasSpell(), TrainerSpell::IsCastable(), Player::learnSpell(), LOG_DEBUG, Player::ModifyMoney(), Unit::RemoveAurasByType(), TrainerSpell::reqSpell, SendPacket(), Unit::SendPlaySpellImpact(), Unit::SendPlaySpellVisual(), SMSG_TRAINER_BUY_SUCCEEDED, TrainerSpell::spell, SPELL_AURA_FEIGN_DEATH, TrainerSpell::spellCost, ObjectGuid::ToString(), TRAINER_SPELL_GREEN, UNIT_NPC_FLAG_TRAINER, and UNIT_STATE_DIED.

Referenced by OpcodeTable::Initialize().

◆ HandleTrainerListOpcode()

void WorldSession::HandleTrainerListOpcode ( WorldPacket recvPacket)
80{
81 ObjectGuid guid;
82
83 recvData >> guid;
84 SendTrainerList(guid);
85}
void SendTrainerList(ObjectGuid guid)
Definition: NPCHandler.cpp:87

References SendTrainerList().

Referenced by OpcodeTable::Initialize().

◆ HandleTurnInPetitionOpcode()

void WorldSession::HandleTurnInPetitionOpcode ( WorldPacket recvData)
642{
643 LOG_DEBUG("network", "Received opcode CMSG_TURN_IN_PETITION");
644
645 // Get petition guid from packet
646 WorldPacket data;
647 ObjectGuid petitionGuid;
648
649 recvData >> petitionGuid;
650
651 // Check if player really has the required petition charter
652 Item* item = _player->GetItemByGuid(petitionGuid);
653 if (!item)
654 return;
655
656 LOG_DEBUG("network", "Petition {} turned in by {}", petitionGuid.ToString(), _player->GetGUID().ToString());
657
658 Petition const* petition = sPetitionMgr->GetPetition(petitionGuid);
659 if (!petition)
660 {
661 LOG_ERROR("network.opcode", "Player {} ({}) tried to turn in petition ({}) that is not present in the database",
662 _player->GetName(), _player->GetGUID().ToString(), petitionGuid.ToString());
663 return;
664 }
665
666 ObjectGuid ownerGuid = petition->ownerGuid;
667 uint8 type = petition->petitionType;
668 std::string name = petition->petitionName;
669
670 // Only the petition owner can turn in the petition
671 if (_player->GetGUID() != ownerGuid)
672 return;
673
674 // Petition type (guild/arena) specific checks
675 if (type == GUILD_CHARTER_TYPE)
676 {
677 // Check if player is already in a guild
678 if (_player->GetGuildId())
679 {
682 SendPacket(&data);
683 return;
684 }
685
686 // Check if guild name is already taken
687 if (sGuildMgr->GetGuildByName(name))
688 {
690 return;
691 }
692 }
693 else
694 {
695 // Check for valid arena bracket (2v2, 3v3, 5v5)
696 uint8 slot = ArenaTeam::GetSlotByType(type);
697 if (slot >= MAX_ARENA_SLOT)
698 return;
699
700 // Check if player is already in an arena team
701 if (_player->GetArenaTeamId(slot))
702 {
704 return;
705 }
706
707 // Check if arena team name is already taken
708 if (sArenaTeamMgr->GetArenaTeamByName(name))
709 {
711 return;
712 }
713 }
714
715 // Get petition signatures from db
716 Signatures const* signatures = sPetitionMgr->GetSignature(petitionGuid);
717 uint8 signs = signatures ? signatures->signatureMap.size() : 0;
718 SignatureMap signatureCopy;
719 if (signs)
720 signatureCopy = signatures->signatureMap;
721
722 uint32 requiredSignatures;
723 if (type == GUILD_CHARTER_TYPE)
724 requiredSignatures = sWorld->getIntConfig(CONFIG_MIN_PETITION_SIGNS);
725 else
726 requiredSignatures = type - 1;
727
728 // Notify player if signatures are missing
729 if (signs < requiredSignatures)
730 {
733 SendPacket(&data);
734 return;
735 }
736
737 // Proceed with guild/arena team creation
738
739 // Delete charter item
740 _player->DestroyItem(item->GetBagSlot(), item->GetSlot(), true);
741
742 if (type == GUILD_CHARTER_TYPE)
743 {
744 // Create guild
745 Guild* guild = new Guild;
746
747 if (!guild->Create(_player, name))
748 {
749 delete guild;
750 return;
751 }
752
753 // Register guild and add guild master
754 sGuildMgr->AddGuild(guild);
755
757
758 // Add members from signatures
759 if (signs)
760 for (SignatureMap::const_iterator itr = signatureCopy.begin(); itr != signatureCopy.end(); ++itr)
761 guild->AddMember(itr->first);
762 }
763 else
764 {
765 // Receive the rest of the packet in arena team creation case
766 uint32 background, icon, iconcolor, border, bordercolor;
767 recvData >> background >> icon >> iconcolor >> border >> bordercolor;
768
769 // Create arena team
770 ArenaTeam* arenaTeam = new ArenaTeam();
771
772 if (!arenaTeam->Create(_player->GetGUID(), type, name, background, icon, iconcolor, border, bordercolor))
773 {
774 delete arenaTeam;
775 return;
776 }
777
778 // Register arena team
779 sArenaTeamMgr->AddArenaTeam(arenaTeam);
780 LOG_DEBUG("network", "PetitonsHandler: Arena team (guid: {}) added to ObjectMgr", arenaTeam->GetId());
781
782 // Add members
783 if (signs)
784 for (SignatureMap::const_iterator itr = signatureCopy.begin(); itr != signatureCopy.end(); ++itr)
785 {
786 LOG_DEBUG("network", "PetitionsHandler: Adding arena team (guid: {}) member {}", arenaTeam->GetId(), itr->first.ToString());
787 arenaTeam->AddMember(itr->first);
788 }
789 }
790
791 CharacterDatabaseTransaction trans = CharacterDatabase.BeginTransaction();
792
794 stmt->SetData(0, petitionGuid.GetCounter());
795 trans->Append(stmt);
796
797 stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_PETITION_SIGNATURE_BY_GUID);
798 stmt->SetData(0, petitionGuid.GetCounter());
799 trans->Append(stmt);
800
801 CharacterDatabase.CommitTransaction(trans);
802
803 // xinef: clear petition store (petition and signatures)
804 sPetitionMgr->RemovePetition(petitionGuid);
805
806 // created
807 LOG_DEBUG("network", "TURN IN PETITION {}", petitionGuid.ToString());
808
810 data << (uint32)PETITION_TURN_OK;
811 SendPacket(&data);
812}
@ ERR_GUILD_COMMAND_SUCCESS
Definition: Guild.h:122
@ PETITION_TURN_NEED_MORE_SIGNATURES
Definition: Guild.h:176
@ PETITION_TURN_ALREADY_IN_GUILD
Definition: Guild.h:175
@ PETITION_TURN_OK
Definition: Guild.h:174
@ CONFIG_MIN_PETITION_SIGNS
Definition: IWorld.h:252
std::map< ObjectGuid, uint32 > SignatureMap
Definition: PetitionMgr.h:37
@ CHAR_DEL_PETITION_BY_GUID
Definition: CharacterDatabase.h:382
@ CHAR_DEL_PETITION_SIGNATURE_BY_GUID
Definition: CharacterDatabase.h:383
@ SMSG_TURN_IN_PETITION_RESULTS
Definition: Opcodes.h:483
bool Create(ObjectGuid captainGuid, uint8 type, std::string const &teamName, uint32 backgroundColor, uint8 emblemStyle, uint32 emblemColor, uint8 borderStyle, uint32 borderColor)
Definition: ArenaTeam.cpp:47
bool Create(Player *pLeader, std::string_view name)
Definition: Guild.cpp:1049
bool AddMember(ObjectGuid guid, uint8 rankId=GUILD_RANK_NONE)
Definition: Guild.cpp:2175
std::string petitionName
Definition: PetitionMgr.h:44

References _player, Guild::AddMember(), ArenaTeam::AddMember(), CHAR_DEL_PETITION_BY_GUID, CHAR_DEL_PETITION_SIGNATURE_BY_GUID, CharacterDatabase, CONFIG_MIN_PETITION_SIGNS, ArenaTeam::Create(), Guild::Create(), Player::DestroyItem(), ERR_ALREADY_IN_ARENA_TEAM, ERR_ARENA_TEAM_CREATE_S, ERR_ARENA_TEAM_NAME_EXISTS_S, ERR_GUILD_COMMAND_SUCCESS, ERR_GUILD_NAME_EXISTS_S, Player::GetArenaTeamId(), Item::GetBagSlot(), ObjectGuid::GetCounter(), Object::GetGUID(), Player::GetGuildId(), ArenaTeam::GetId(), Player::GetItemByGuid(), WorldObject::GetName(), Item::GetSlot(), ArenaTeam::GetSlotByType(), GUILD_CHARTER_TYPE, GUILD_COMMAND_CREATE, WorldPacket::Initialize(), LOG_DEBUG, LOG_ERROR, MAX_ARENA_SLOT, Petition::ownerGuid, PETITION_TURN_ALREADY_IN_GUILD, PETITION_TURN_NEED_MORE_SIGNATURES, PETITION_TURN_OK, Petition::petitionName, Petition::petitionType, sArenaTeamMgr, SendArenaTeamCommandResult(), Guild::SendCommandResult(), SendPacket(), PreparedStatementBase::SetData(), sGuildMgr, Signatures::signatureMap, SMSG_TURN_IN_PETITION_RESULTS, sPetitionMgr, sWorld, and ObjectGuid::ToString().

Referenced by OpcodeTable::Initialize().

◆ HandleTutorialClear()

void WorldSession::HandleTutorialClear ( WorldPacket recvData)
1294{
1295 for (uint8 i = 0; i < MAX_ACCOUNT_TUTORIAL_VALUES; ++i)
1296 SetTutorialInt(i, 0xFFFFFFFF);
1297}
#define MAX_ACCOUNT_TUTORIAL_VALUES
Definition: Common.h:82
void SetTutorialInt(uint8 index, uint32 value)
Definition: WorldSession.h:459

References MAX_ACCOUNT_TUTORIAL_VALUES, and SetTutorialInt().

Referenced by OpcodeTable::Initialize().

◆ HandleTutorialFlag()

void WorldSession::HandleTutorialFlag ( WorldPacket recvData)
1278{
1279 uint32 data;
1280 recvData >> data;
1281
1282 uint8 index = uint8(data / 32);
1283 if (index >= MAX_ACCOUNT_TUTORIAL_VALUES)
1284 return;
1285
1286 uint32 value = (data % 32);
1287
1288 uint32 flag = GetTutorialInt(index);
1289 flag |= (1 << value);
1290 SetTutorialInt(index, flag);
1291}
uint32 GetTutorialInt(uint8 index) const
Definition: WorldSession.h:458

References GetTutorialInt(), MAX_ACCOUNT_TUTORIAL_VALUES, and SetTutorialInt().

Referenced by OpcodeTable::Initialize().

◆ HandleTutorialReset()

void WorldSession::HandleTutorialReset ( WorldPacket recvData)
1300{
1301 for (uint8 i = 0; i < MAX_ACCOUNT_TUTORIAL_VALUES; ++i)
1302 SetTutorialInt(i, 0x00000000);
1303}

References MAX_ACCOUNT_TUTORIAL_VALUES, and SetTutorialInt().

Referenced by OpcodeTable::Initialize().

◆ HandleUnacceptTradeOpcode()

void WorldSession::HandleUnacceptTradeOpcode ( WorldPacket recvPacket)
511{
512 TradeData* my_trade = _player->GetTradeData();
513 if (!my_trade)
514 return;
515
516 my_trade->SetAccepted(false, true);
517}

References _player, Player::GetTradeData(), and TradeData::SetAccepted().

Referenced by OpcodeTable::Initialize().

◆ HandleUnlearnSkillOpcode()

void WorldSession::HandleUnlearnSkillOpcode ( WorldPacket recvPacket)
92{
93 uint32 skillId;
94 recvData >> skillId;
95
96 if (!IsPrimaryProfessionSkill(skillId))
97 return;
98
99 GetPlayer()->SetSkill(skillId, 0, 0, 0);
100}
bool IsPrimaryProfessionSkill(uint32 skill)
Definition: SpellMgr.cpp:36
void SetSkill(uint16 id, uint16 step, uint16 currVal, uint16 maxVal)
Definition: Player.cpp:5316

References GetPlayer(), IsPrimaryProfessionSkill(), and Player::SetSkill().

Referenced by OpcodeTable::Initialize().

◆ HandleUnstablePet()

void WorldSession::HandleUnstablePet ( WorldPacket recvPacket)
619{
620 LOG_DEBUG("network", "WORLD: Recv CMSG_UNSTABLE_PET.");
621 ObjectGuid npcGUID;
622 uint32 petnumber;
623
624 recvData >> npcGUID >> petnumber;
625
626 if (!CheckStableMaster(npcGUID))
627 {
629 return;
630 }
631
632 // remove fake death
633 if (GetPlayer()->HasUnitState(UNIT_STATE_DIED))
635
636 PetStable* petStable = GetPlayer()->GetPetStable();
637 if (!petStable)
638 {
640 return;
641 }
642
643 auto stabledPet = std::find_if(petStable->StabledPets.begin(), petStable->StabledPets.end(), [petnumber](Optional<PetStable::PetInfo> const& pet)
644 {
645 return pet && pet->PetNumber == petnumber;
646 });
647
648 if (stabledPet == petStable->StabledPets.end())
649 {
651 return;
652 }
653
654 CreatureTemplate const* creatureInfo = sObjectMgr->GetCreatureTemplate((*stabledPet)->CreatureId);
655 if (!creatureInfo || !creatureInfo->IsTameable(_player->CanTameExoticPets()))
656 {
657 // if problem in exotic pet
658 if (creatureInfo && creatureInfo->IsTameable(true))
660 else
662
663 return;
664 }
665
666 Pet* oldPet = _player->GetPet();
667 if (oldPet)
668 {
669 // try performing a swap, client sends this packet instead of swap when starting from stabled slot
670 if (!oldPet->IsAlive() || !oldPet->IsHunterPet())
671 {
673 return;
674 }
675
676 _player->RemovePet(oldPet, PetSaveMode(PET_SAVE_FIRST_STABLE_SLOT + std::distance(petStable->StabledPets.begin(), stabledPet)));
677 }
678 else if (petStable->UnslottedPets.size() == 1)
679 {
680 if (petStable->CurrentPet || !petStable->UnslottedPets[0].Health || petStable->UnslottedPets[0].Type != HUNTER_PET)
681 {
683 return;
684 }
685
687 stmt->SetData(0, PetSaveMode(PET_SAVE_FIRST_STABLE_SLOT + std::distance(petStable->StabledPets.begin(), stabledPet)));
688 stmt->SetData(1, _player->GetGUID().GetCounter());
689 stmt->SetData(2, petStable->UnslottedPets[0].PetNumber);
690 CharacterDatabase.Execute(stmt);
691
692 // move unsummoned pet into CurrentPet slot so that it gets moved into stable slot later
693 petStable->CurrentPet = std::move(petStable->UnslottedPets.back());
694 petStable->UnslottedPets.pop_back();
695 }
696 else if (petStable->CurrentPet || !petStable->UnslottedPets.empty())
697 {
699 return;
700 }
701
702 Pet* newPet = new Pet(_player, HUNTER_PET);
703 if (!newPet->LoadPetFromDB(_player, 0, petnumber, false))
704 {
705 delete newPet;
706
707 petStable->UnslottedPets.push_back(std::move(*petStable->CurrentPet));
708 petStable->CurrentPet.reset();
709
710 // update current pet slot in db immediately to maintain slot consistency, dismissed pet was already saved
713 stmt->SetData(1, _player->GetGUID().GetCounter());
714 stmt->SetData(2, petnumber);
715 CharacterDatabase.Execute(stmt);
716
718 }
719 else
720 {
721 // update current pet slot in db immediately to maintain slot consistency, dismissed pet was already saved
724 stmt->SetData(1, _player->GetGUID().GetCounter());
725 stmt->SetData(2, petnumber);
726 CharacterDatabase.Execute(stmt);
727
729 }
730}

References _player, Player::CanTameExoticPets(), CHAR_UPD_CHAR_PET_SLOT_BY_ID, CharacterDatabase, CheckStableMaster(), PetStable::CurrentPet, ObjectGuid::GetCounter(), Object::GetGUID(), Player::GetPet(), Player::GetPetStable(), GetPlayer(), HUNTER_PET, Unit::IsAlive(), Unit::IsHunterPet(), CreatureTemplate::IsTameable(), Pet::LoadPetFromDB(), LOG_DEBUG, PET_SAVE_AS_CURRENT, PET_SAVE_FIRST_STABLE_SLOT, PET_SAVE_NOT_IN_SLOT, Unit::RemoveAurasByType(), Player::RemovePet(), SendStableResult(), PreparedStatementBase::SetData(), sObjectMgr, SPELL_AURA_FEIGN_DEATH, STABLE_ERR_EXOTIC, STABLE_ERR_STABLE, STABLE_SUCCESS_UNSTABLE, PetStable::StabledPets, UNIT_STATE_DIED, and PetStable::UnslottedPets.

Referenced by OpcodeTable::Initialize().

◆ HandleUpdateAccountData()

void WorldSession::HandleUpdateAccountData ( WorldPacket recvPacket)
848{
849 uint32 type, timestamp, decompressedSize;
850 recv_data >> type >> timestamp >> decompressedSize;
851
852 LOG_DEBUG("network", "UAD: type {}, time {}, decompressedSize {}", type, timestamp, decompressedSize);
853
854 if (type >= NUM_ACCOUNT_DATA_TYPES)
855 return;
856
857 if (decompressedSize == 0) // erase
858 {
859 SetAccountData(AccountDataType(type), 0, "");
860
862 data << uint32(type);
863 data << uint32(0);
864 SendPacket(&data);
865
866 return;
867 }
868
869 if (decompressedSize > 0xFFFF)
870 {
871 recv_data.rfinish(); // unnneded warning spam in this case
872 LOG_ERROR("network.opcode", "UAD: Account data packet too big, size {}", decompressedSize);
873 return;
874 }
875
876 ByteBuffer dest;
877 dest.resize(decompressedSize);
878
879 uLongf realSize = decompressedSize;
880 if (uncompress(dest.contents(), &realSize, recv_data.contents() + recv_data.rpos(), recv_data.size() - recv_data.rpos()) != Z_OK)
881 {
882 recv_data.rfinish(); // unnneded warning spam in this case
883 LOG_ERROR("network.opcode", "UAD: Failed to decompress account data");
884 return;
885 }
886
887 recv_data.rfinish(); // uncompress read (recv_data.size() - recv_data.rpos())
888
889 std::string adata;
890 dest >> adata;
891
892 SetAccountData(AccountDataType(type), timestamp, adata);
893
895 data << uint32(type);
896 data << uint32(0);
897 SendPacket(&data);
898}
@ SMSG_UPDATE_ACCOUNT_DATA_COMPLETE
Definition: Opcodes.h:1153
void SetAccountData(AccountDataType type, time_t tm, std::string const &data)
Definition: WorldSession.cpp:875

References ByteBuffer::contents(), LOG_DEBUG, LOG_ERROR, NUM_ACCOUNT_DATA_TYPES, ByteBuffer::resize(), ByteBuffer::rfinish(), ByteBuffer::rpos(), SendPacket(), SetAccountData(), ByteBuffer::size(), and SMSG_UPDATE_ACCOUNT_DATA_COMPLETE.

Referenced by OpcodeTable::Initialize().

◆ HandleUpdateMissileTrajectory()

void WorldSession::HandleUpdateMissileTrajectory ( WorldPacket recvPacket)
1747{
1748 LOG_DEBUG("network", "WORLD: CMSG_UPDATE_MISSILE_TRAJECTORY");
1749
1750 ObjectGuid guid;
1751 uint32 spellId;
1752 float elevation, speed;
1753 float curX, curY, curZ;
1754 float targetX, targetY, targetZ;
1755 uint8 moveStop;
1756
1757 recvPacket >> guid >> spellId >> elevation >> speed;
1758 recvPacket >> curX >> curY >> curZ;
1759 recvPacket >> targetX >> targetY >> targetZ;
1760 recvPacket >> moveStop;
1761
1762 Unit* caster = ObjectAccessor::GetUnit(*_player, guid);
1763 Spell* spell = caster ? caster->GetCurrentSpell(CURRENT_GENERIC_SPELL) : nullptr;
1764 if (!spell || spell->m_spellInfo->Id != spellId || !spell->m_targets.HasDst() || !spell->m_targets.HasSrc())
1765 {
1766 recvPacket.rfinish();
1767 return;
1768 }
1769
1770 Position pos = *spell->m_targets.GetSrcPos();
1771 pos.Relocate(curX, curY, curZ);
1772 spell->m_targets.ModSrc(pos);
1773
1774 pos = *spell->m_targets.GetDstPos();
1775 pos.Relocate(targetX, targetY, targetZ);
1776 spell->m_targets.ModDst(pos);
1777
1778 spell->m_targets.SetElevation(elevation);
1779 spell->m_targets.SetSpeed(speed);
1780
1781 if (moveStop)
1782 {
1783 uint32 opcode;
1784 recvPacket >> opcode;
1785 recvPacket.SetOpcode(opcode);
1786 HandleMovementOpcodes(recvPacket);
1787 }
1788}
@ CURRENT_GENERIC_SPELL
Definition: Unit.h:538
void ModDst(Position const &pos)
Definition: Spell.cpp:435
bool HasSrc() const
Definition: Spell.h:164
bool HasDst() const
Definition: Spell.h:165
void ModSrc(Position const &pos)
Definition: Spell.cpp:384
Position const * GetSrcPos() const
Definition: Spell.cpp:361
WorldLocation const * GetDstPos() const
Definition: Spell.cpp:400

References _player, CURRENT_GENERIC_SPELL, Unit::GetCurrentSpell(), SpellCastTargets::GetDstPos(), SpellCastTargets::GetSrcPos(), ObjectAccessor::GetUnit(), HandleMovementOpcodes(), SpellCastTargets::HasDst(), SpellCastTargets::HasSrc(), SpellInfo::Id, LOG_DEBUG, Spell::m_spellInfo, Spell::m_targets, SpellCastTargets::ModDst(), SpellCastTargets::ModSrc(), Position::Relocate(), ByteBuffer::rfinish(), SpellCastTargets::SetElevation(), WorldPacket::SetOpcode(), and SpellCastTargets::SetSpeed().

Referenced by OpcodeTable::Initialize().

◆ HandleUpdateProjectilePosition()

void WorldSession::HandleUpdateProjectilePosition ( WorldPacket recvPacket)
758{
759 LOG_DEBUG("network", "WORLD: CMSG_UPDATE_PROJECTILE_POSITION");
760
761 ObjectGuid casterGuid;
762 uint32 spellId;
763 uint8 castCount;
764 float x, y, z; // Position of missile hit
765
766 recvPacket >> casterGuid;
767 recvPacket >> spellId;
768 recvPacket >> castCount;
769 recvPacket >> x;
770 recvPacket >> y;
771 recvPacket >> z;
772
773 Unit* caster = ObjectAccessor::GetUnit(*_player, casterGuid);
774 if (!caster)
775 return;
776
777 Spell* spell = caster->FindCurrentSpellBySpellId(spellId);
778 if (!spell || !spell->m_targets.HasDst())
779 return;
780
781 Position pos = *spell->m_targets.GetDstPos();
782 pos.Relocate(x, y, z);
783 spell->m_targets.ModDst(pos);
784
786 data << casterGuid;
787 data << uint8(castCount);
788 data << float(x);
789 data << float(y);
790 data << float(z);
791 caster->SendMessageToSet(&data, true);
792}
@ SMSG_SET_PROJECTILE_POSITION
Definition: Opcodes.h:1245
Spell * FindCurrentSpellBySpellId(uint32 spell_id) const
Definition: Unit.cpp:4125

References _player, Unit::FindCurrentSpellBySpellId(), SpellCastTargets::GetDstPos(), ObjectAccessor::GetUnit(), SpellCastTargets::HasDst(), LOG_DEBUG, Spell::m_targets, SpellCastTargets::ModDst(), Position::Relocate(), WorldObject::SendMessageToSet(), and SMSG_SET_PROJECTILE_POSITION.

Referenced by OpcodeTable::Initialize().

◆ HandleUseItemOpcode()

void WorldSession::HandleUseItemOpcode ( WorldPacket recvPacket)
Todo:
: add targets.read() check
59{
61 Player* pUser = _player;
62
63 // ignore for remote control state
64 if (pUser->m_mover != pUser)
65 return;
66
67 uint8 bagIndex, slot, castFlags;
68 uint8 castCount; // next cast if exists (single or not)
69 ObjectGuid itemGUID;
70 uint32 glyphIndex; // something to do with glyphs?
71 uint32 spellId; // casted spell id
72
73 recvPacket >> bagIndex >> slot >> castCount >> spellId >> itemGUID >> glyphIndex >> castFlags;
74
75 if (glyphIndex >= MAX_GLYPH_SLOT_INDEX)
76 {
77 pUser->SendEquipError(EQUIP_ERR_ITEM_NOT_FOUND, nullptr, nullptr);
78 return;
79 }
80
81 Item* pItem = pUser->GetUseableItemByPos(bagIndex, slot);
82 if (!pItem)
83 {
84 pUser->SendEquipError(EQUIP_ERR_ITEM_NOT_FOUND, nullptr, nullptr);
85 return;
86 }
87
88 if (pItem->GetGUID() != itemGUID)
89 {
90 pUser->SendEquipError(EQUIP_ERR_ITEM_NOT_FOUND, nullptr, nullptr);
91 return;
92 }
93
94 LOG_DEBUG("network", "WORLD: CMSG_USE_ITEM packet, bagIndex: {}, slot: {}, castCount: {}, spellId: {}, Item: {}, glyphIndex: {}, data length = {}", bagIndex, slot, castCount, spellId, pItem->GetEntry(), glyphIndex, (uint32)recvPacket.size());
95
96 ItemTemplate const* proto = pItem->GetTemplate();
97 if (!proto)
98 {
99 pUser->SendEquipError(EQUIP_ERR_ITEM_NOT_FOUND, pItem, nullptr);
100 return;
101 }
102
103 // some item classes can be used only in equipped state
104 if (proto->InventoryType != INVTYPE_NON_EQUIP && !pItem->IsEquipped())
105 {
106 pUser->SendEquipError(EQUIP_ERR_ITEM_NOT_FOUND, pItem, nullptr);
107 return;
108 }
109
110 InventoryResult msg = pUser->CanUseItem(pItem);
111 if (msg != EQUIP_ERR_OK)
112 {
113 pUser->SendEquipError(msg, pItem, nullptr);
114 return;
115 }
116
117 // only allow conjured consumable, bandage, poisons (all should have the 2^21 item flag set in DB)
119 {
120 pUser->SendEquipError(EQUIP_ERR_NOT_DURING_ARENA_MATCH, pItem, nullptr);
121 return;
122 }
123
124 // don't allow items banned in arena
125 if (proto->HasFlag(ITEM_FLAG_NOT_USEABLE_IN_ARENA) && pUser->InArena())
126 {
127 pUser->SendEquipError(EQUIP_ERR_NOT_DURING_ARENA_MATCH, pItem, nullptr);
128 return;
129 }
130
131 if (pUser->IsInCombat())
132 {
133 for (int i = 0; i < MAX_ITEM_PROTO_SPELLS; ++i)
134 {
135 if (SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(proto->Spells[i].SpellId))
136 {
137 if (!spellInfo->CanBeUsedInCombat())
138 {
139 pUser->SendEquipError(EQUIP_ERR_NOT_IN_COMBAT, pItem, nullptr);
140 return;
141 }
142 }
143 }
144 }
145
146 // check also BIND_WHEN_PICKED_UP and BIND_QUEST_ITEM for .additem or .additemset case by GM (not binded at adding to inventory)
148 {
149 if (!pItem->IsSoulBound())
150 {
151 pItem->SetState(ITEM_CHANGED, pUser);
152 pItem->SetBinding(true);
153 }
154 }
155
156 SpellCastTargets targets;
157 targets.Read(recvPacket, pUser);
158 HandleClientCastFlags(recvPacket, castFlags, targets);
159
160 // Note: If script stop casting it must send appropriate data to client to prevent stuck item in gray state.
161 if (!sScriptMgr->OnItemUse(pUser, pItem, targets))
162 {
163 // no script or script not process request by self
164 pUser->CastItemUseSpell(pItem, targets, castCount, glyphIndex);
165 }
166}
@ INVTYPE_NON_EQUIP
Definition: ItemTemplate.h:256
@ ITEM_FLAG_IGNORE_DEFAULT_ARENA_RESTRICTIONS
Definition: ItemTemplate.h:168
@ ITEM_FLAG_NOT_USEABLE_IN_ARENA
Definition: ItemTemplate.h:173
@ BIND_WHEN_USE
Definition: ItemTemplate.h:98
@ BIND_QUEST_ITEM
Definition: ItemTemplate.h:99
@ BIND_WHEN_PICKED_UP
Definition: ItemTemplate.h:96
@ ITEM_CLASS_CONSUMABLE
Definition: ItemTemplate.h:291
@ EQUIP_ERR_NOT_DURING_ARENA_MATCH
Definition: Item.h:124
@ EQUIP_ERR_NOT_IN_COMBAT
Definition: Item.h:107
void SetBinding(bool val)
Definition: Item.h:235
Item * GetUseableItemByPos(uint8 bag, uint8 slot) const
Definition: Player.h:1244
void CastItemUseSpell(Item *item, SpellCastTargets const &targets, uint8 cast_count, uint32 glyphIndex)
Definition: Player.cpp:7377

References _player, BIND_QUEST_ITEM, BIND_WHEN_PICKED_UP, BIND_WHEN_USE, ItemTemplate::Bonding, Player::CanUseItem(), Player::CastItemUseSpell(), ItemTemplate::Class, EQUIP_ERR_ITEM_NOT_FOUND, EQUIP_ERR_NOT_DURING_ARENA_MATCH, EQUIP_ERR_NOT_IN_COMBAT, EQUIP_ERR_OK, Object::GetEntry(), Object::GetGUID(), Item::GetTemplate(), Player::GetUseableItemByPos(), HandleClientCastFlags(), ItemTemplate::HasFlag(), Player::InArena(), ItemTemplate::InventoryType, INVTYPE_NON_EQUIP, Item::IsEquipped(), Unit::IsInCombat(), Item::IsSoulBound(), ITEM_CHANGED, ITEM_CLASS_CONSUMABLE, ITEM_FLAG_IGNORE_DEFAULT_ARENA_RESTRICTIONS, ITEM_FLAG_NOT_USEABLE_IN_ARENA, LOG_DEBUG, Player::m_mover, MAX_GLYPH_SLOT_INDEX, MAX_ITEM_PROTO_SPELLS, SpellCastTargets::Read(), Player::SendEquipError(), Item::SetBinding(), Item::SetState(), ByteBuffer::size(), _Spell::SpellId, ItemTemplate::Spells, sScriptMgr, and sSpellMgr.

Referenced by OpcodeTable::Initialize().

◆ HandleVoiceSessionEnableOpcode()

void WorldSession::HandleVoiceSessionEnableOpcode ( WorldPacket recvData)
24{
25 LOG_DEBUG("network", "WORLD: CMSG_VOICE_SESSION_ENABLE");
26 // uint8 isVoiceEnabled, uint8 isMicrophoneEnabled
27 recvData.read_skip<uint8>();
28 recvData.read_skip<uint8>();
29}

References LOG_DEBUG, and ByteBuffer::read_skip().

Referenced by OpcodeTable::Initialize().

◆ HandleWardenDataOpcode()

void WorldSession::HandleWardenDataOpcode ( WorldPacket recvData)
319{
320 if (!_warden || recvData.empty())
321 return;
322
323 _warden->DecryptData(recvData.contents(), recvData.size());
324 uint8 opcode;
325 recvData >> opcode;
326 LOG_DEBUG("warden", "Got packet, opcode {:02X}, size {}", opcode, uint32(recvData.size()));
327 recvData.hexlike();
328
329 switch (opcode)
330 {
332 _warden->SendModuleToClient();
333 break;
335 _warden->RequestHash();
336 break;
338 _warden->HandleData(recvData);
339 break;
341 LOG_DEBUG("warden", "NYI WARDEN_CMSG_MEM_CHECKS_RESULT received!");
342 break;
344 _warden->HandleHashResult(recvData);
345 _warden->InitializeModule();
346 break;
348 LOG_DEBUG("warden", "NYI WARDEN_CMSG_MODULE_FAILED received!");
349 break;
350 default:
351 LOG_DEBUG("warden", "Got unknown warden opcode {:02X} of size {}.", opcode, uint32(recvData.size() - 1));
352 break;
353 }
354}
@ WARDEN_CMSG_MODULE_MISSING
Definition: Warden.h:31
@ WARDEN_CMSG_HASH_RESULT
Definition: Warden.h:35
@ WARDEN_CMSG_MODULE_FAILED
Definition: Warden.h:36
@ WARDEN_CMSG_CHEAT_CHECKS_RESULT
Definition: Warden.h:33
@ WARDEN_CMSG_MODULE_OK
Definition: Warden.h:32
@ WARDEN_CMSG_MEM_CHECKS_RESULT
Definition: Warden.h:34
void hexlike() const
Definition: ByteBuffer.cpp:188

References _warden, ByteBuffer::contents(), ByteBuffer::empty(), ByteBuffer::hexlike(), LOG_DEBUG, ByteBuffer::size(), WARDEN_CMSG_CHEAT_CHECKS_RESULT, WARDEN_CMSG_HASH_RESULT, WARDEN_CMSG_MEM_CHECKS_RESULT, WARDEN_CMSG_MODULE_FAILED, WARDEN_CMSG_MODULE_MISSING, and WARDEN_CMSG_MODULE_OK.

Referenced by OpcodeTable::Initialize().

◆ HandleWhoisOpcode()

void WorldSession::HandleWhoisOpcode ( WorldPacket recvData)
1125{
1126 LOG_DEBUG("network", "Received opcode CMSG_WHOIS");
1127 std::string charname;
1128 recv_data >> charname;
1129
1131 {
1133 return;
1134 }
1135
1136 if (charname.empty() || !normalizePlayerName (charname))
1137 {
1139 return;
1140 }
1141
1142 Player* player = ObjectAccessor::FindPlayerByName(charname, false);
1143
1144 if (!player)
1145 {
1147 return;
1148 }
1149
1150 uint32 accid = player->GetSession()->GetAccountId();
1151
1153
1154 stmt->SetData(0, accid);
1155
1156 PreparedQueryResult result = LoginDatabase.Query(stmt);
1157
1158 if (!result)
1159 {
1161 return;
1162 }
1163
1164 Field* fields = result->Fetch();
1165 std::string acc = fields[0].Get<std::string>();
1166 if (acc.empty())
1167 acc = "Unknown";
1168 std::string email = fields[1].Get<std::string>();
1169 if (email.empty())
1170 email = "Unknown";
1171 std::string lastip = fields[2].Get<std::string>();
1172 if (lastip.empty())
1173 lastip = "Unknown";
1174
1175 std::string msg = charname + "'s " + "account is " + acc + ", e-mail: " + email + ", last ip: " + lastip;
1176
1177 WorldPacket data(SMSG_WHOIS, msg.size() + 1);
1178 data << msg;
1179 SendPacket(&data);
1180
1181 LOG_DEBUG("network", "Received whois command from player {} for character {}", GetPlayer()->GetName(), charname);
1182}
@ LANG_PLAYER_NOT_EXIST_OR_OFFLINE
Definition: Language.h:745
@ LANG_ACCOUNT_FOR_PLAYER_NOT_FOUND
Definition: Language.h:746
@ LANG_PERMISSION_DENIED
Definition: Language.h:741
@ LANG_NEED_CHARACTER_NAME
Definition: Language.h:744
@ LOGIN_SEL_ACCOUNT_WHOIS
Definition: LoginDatabase.h:96
@ SMSG_WHOIS
Definition: Opcodes.h:131
bool IsAdminAccount(uint32 gmlevel)
Definition: AccountMgr.cpp:310

References ObjectAccessor::FindPlayerByName(), Field::Get(), GetAccountId(), GetPlayer(), GetSecurity(), Player::GetSession(), AccountMgr::IsAdminAccount(), LANG_ACCOUNT_FOR_PLAYER_NOT_FOUND, LANG_NEED_CHARACTER_NAME, LANG_PERMISSION_DENIED, LANG_PLAYER_NOT_EXIST_OR_OFFLINE, LOG_DEBUG, LOGIN_SEL_ACCOUNT_WHOIS, LoginDatabase, normalizePlayerName(), ChatHandler::SendNotification(), SendPacket(), PreparedStatementBase::SetData(), and SMSG_WHOIS.

Referenced by OpcodeTable::Initialize().

◆ HandleWhoOpcode()

void WorldSession::HandleWhoOpcode ( WorldPacket recvPacket)
212{
213 LOG_DEBUG("network", "WORLD: Recvd CMSG_WHO Message");
214
215 uint32 matchCount = 0;
216
217 uint32 levelMin, levelMax, racemask, classmask, zonesCount, strCount;
218 std::array<uint32, 10> zoneids = {}; // 10 is client limit
219 std::string packetPlayerName, packetGuildName;
220
221 recvData >> levelMin; // maximal player level, default 0
222 recvData >> levelMax; // minimal player level, default 100 (MAX_LEVEL)
223 recvData >> packetPlayerName; // player name, case sensitive...
224
225 recvData >> packetGuildName; // guild name, case sensitive...
226
227 recvData >> racemask; // race mask
228 recvData >> classmask; // class mask
229 recvData >> zonesCount; // zones count, client limit = 10 (2.0.10)
230
231 if (zonesCount > 10)
232 return; // can't be received from real client or broken packet
233
234 for (uint32 i = 0; i < zonesCount; ++i)
235 {
236 uint32 temp;
237 recvData >> temp; // zone id, 0 if zone is unknown...
238 zoneids[i] = temp;
239 LOG_DEBUG("network.who", "Zone {}: {}", i, zoneids[i]);
240 }
241
242 recvData >> strCount; // user entered strings count, client limit=4 (checked on 2.0.10)
243
244 if (strCount > 4)
245 return; // can't be received from real client or broken packet
246
247 LOG_DEBUG("network.who", "Minlvl {}, maxlvl {}, name {}, guild {}, racemask {}, classmask {}, zones {}, strings {}",
248 levelMin, levelMax, packetPlayerName, packetGuildName, racemask, classmask, zonesCount, strCount);
249
250 std::wstring str[4]; // 4 is client limit
251 for (uint32 i = 0; i < strCount; ++i)
252 {
253 std::string temp;
254 recvData >> temp; // user entered string, it used as universal search pattern(guild+player name)?
255
256 if (!Utf8toWStr(temp, str[i]))
257 continue;
258
259 wstrToLower(str[i]);
260
261 LOG_DEBUG("network.who", "String {}: {}", i, temp);
262 }
263
264 std::wstring wpacketPlayerName;
265 std::wstring wpacketGuildName;
266 if (!(Utf8toWStr(packetPlayerName, wpacketPlayerName) && Utf8toWStr(packetGuildName, wpacketGuildName)))
267 return;
268
269 wstrToLower(wpacketPlayerName);
270 wstrToLower(wpacketGuildName);;
271
272 // client send in case not set max level value 100 but Acore supports 255 max level,
273 // update it to show GMs with characters after 100 level
274 if (levelMax >= MAX_LEVEL)
275 levelMax = STRONG_MAX_LEVEL;
276
277 uint32 team = _player->GetTeamId();
278 uint32 security = GetSecurity();
279 bool allowTwoSideWhoList = sWorld->getBoolConfig(CONFIG_ALLOW_TWO_SIDE_WHO_LIST);
280 uint32 gmLevelInWhoList = sWorld->getIntConfig(CONFIG_GM_LEVEL_IN_WHO_LIST);
281 uint32 displaycount = 0;
282
283 WorldPacket data(SMSG_WHO, 50); // guess size
284 data << uint32(matchCount); // placeholder, count of players matching criteria
285 data << uint32(displaycount); // placeholder, count of players displayed
286
287 for (auto const& target : sWhoListCacheMgr->GetWhoList())
288 {
289 if (AccountMgr::IsPlayerAccount(security))
290 {
291 // player can see member of other team only if CONFIG_ALLOW_TWO_SIDE_WHO_LIST
292 if (target.GetTeamId() != team && !allowTwoSideWhoList)
293 {
294 continue;
295 }
296
297 // player can see MODERATOR, GAME MASTER, ADMINISTRATOR only if CONFIG_GM_IN_WHO_LIST
298 if (target.GetSecurity() > AccountTypes(gmLevelInWhoList))
299 {
300 continue;
301 }
302 }
303
304 // check if target is globally visible for player
305 if ((_player->GetGUID() != target.GetGuid() && !target.IsVisible()) &&
307 {
308 continue;
309 }
310
311 // check if target's level is in level range
312 uint8 lvl = target.GetLevel();
313 if (lvl < levelMin || lvl > levelMax)
314 {
315 continue;
316 }
317
318 // check if class matches classmask
319 uint8 class_ = target.GetClass();
320 if (!(classmask & (1 << class_)))
321 {
322 continue;
323 }
324
325 // check if race matches racemask
326 uint32 race = target.GetRace();
327 if (!(racemask & (1 << race)))
328 {
329 continue;
330 }
331
332 uint32 playerZoneId = target.GetZoneId();
333 uint8 gender = target.GetGender();
334
335 bool showZones = true;
336 for (uint32 i = 0; i < zonesCount; ++i)
337 {
338 if (zoneids[i] == playerZoneId)
339 {
340 showZones = true;
341 break;
342 }
343
344 showZones = false;
345 }
346
347 if (!showZones)
348 {
349 continue;
350 }
351
352 std::wstring const& wideplayername = target.GetWidePlayerName();
353 if (!(wpacketPlayerName.empty() || wideplayername.find(wpacketPlayerName) != std::wstring::npos))
354 {
355 continue;
356 }
357
358 std::wstring const& wideguildname = target.GetWideGuildName();
359 if (!(wpacketGuildName.empty() || wideguildname.find(wpacketGuildName) != std::wstring::npos))
360 {
361 continue;
362 }
363
364 std::string aname;
365 if (AreaTableEntry const* areaEntry = sAreaTableStore.LookupEntry(playerZoneId))
366 {
367 aname = areaEntry->area_name[GetSessionDbcLocale()];
368 }
369
370 bool s_show = true;
371 for (uint32 i = 0; i < strCount; ++i)
372 {
373 if (!str[i].empty())
374 {
375 if (wideguildname.find(str[i]) != std::wstring::npos ||
376 wideplayername.find(str[i]) != std::wstring::npos ||
377 Utf8FitTo(aname, str[i]))
378 {
379 s_show = true;
380 break;
381 }
382
383 s_show = false;
384 }
385 }
386
387 if (!s_show)
388 {
389 continue;
390 }
391
392 // 49 is maximum player count sent to client - can be overridden
393 // through config, but is unstable
394 if ((matchCount++) >= sWorld->getIntConfig(CONFIG_MAX_WHO_LIST_RETURN))
395 {
396 continue;
397 }
398
399 data << target.GetPlayerName(); // player name
400 data << target.GetGuildName(); // guild name
401 data << uint32(lvl); // player level
402 data << uint32(class_); // player class
403 data << uint32(race); // player race
404 data << uint8(gender); // player gender
405 data << uint32(playerZoneId); // player zone id
406
407 ++displaycount;
408 }
409
410 data.put(0, displaycount); // insert right count, count displayed
411 data.put(4, matchCount); // insert right count, count of matches
412
413 SendPacket(&data);
414 LOG_DEBUG("network", "WORLD: Send SMSG_WHO Message");
415}
AccountTypes
Definition: Common.h:56
void wstrToLower(std::wstring &str)
Definition: Util.cpp:382
bool Utf8FitTo(std::string_view str, std::wstring_view search)
Definition: Util.cpp:481
#define sWhoListCacheMgr
Definition: WhoListCacheMgr.h:96
@ CONFIG_MAX_WHO_LIST_RETURN
Definition: IWorld.h:399
@ CONFIG_GM_LEVEL_IN_WHO_LIST
Definition: IWorld.h:259
@ CONFIG_ALLOW_TWO_SIDE_WHO_LIST
Definition: IWorld.h:80
#define MAX_LEVEL
Definition: DBCEnums.h:39
#define STRONG_MAX_LEVEL
Definition: DBCEnums.h:43
@ SMSG_WHO
Definition: Opcodes.h:129

References _player, CONFIG_ALLOW_TWO_SIDE_WHO_LIST, CONFIG_GM_LEVEL_IN_WHO_LIST, CONFIG_MAX_WHO_LIST_RETURN, Object::GetGUID(), GetSecurity(), Player::GetSession(), GetSessionDbcLocale(), Player::GetTeamId(), AccountMgr::IsPlayerAccount(), LOG_DEBUG, MAX_LEVEL, ByteBuffer::put(), sAreaTableStore, SendPacket(), SMSG_WHO, STRONG_MAX_LEVEL, sWhoListCacheMgr, sWorld, Utf8FitTo(), Utf8toWStr(), and wstrToLower().

Referenced by OpcodeTable::Initialize().

◆ HandleWorldStateUITimerUpdate()

void WorldSession::HandleWorldStateUITimerUpdate ( WorldPacket recvData)
1634{
1635 // empty opcode
1636 LOG_DEBUG("network", "WORLD: CMSG_WORLD_STATE_UI_TIMER_UPDATE");
1637
1639 response.Time = GameTime::GetGameTime().count();
1640 SendPacket(response.Write());
1641}
Definition: MiscPackets.h:182
WorldPacket const * Write() override
Definition: MiscPackets.cpp:122
uint32 Time
Definition: MiscPackets.h:188

References GameTime::GetGameTime(), LOG_DEBUG, SendPacket(), WorldPackets::Misc::UITime::Time, and WorldPackets::Misc::UITime::Write().

Referenced by OpcodeTable::Initialize().

◆ HandleWorldTeleportOpcode()

void WorldSession::HandleWorldTeleportOpcode ( WorldPacket recvData)
1095{
1096 uint32 time;
1097 uint32 mapid;
1098 float PositionX;
1099 float PositionY;
1100 float PositionZ;
1101 float Orientation;
1102
1103 recv_data >> time; // time in m.sec.
1104 recv_data >> mapid;
1105 recv_data >> PositionX;
1106 recv_data >> PositionY;
1107 recv_data >> PositionZ;
1108 recv_data >> Orientation; // o (3.141593 = 180 degrees)
1109
1110 if (GetPlayer()->IsInFlight())
1111 {
1112 LOG_DEBUG("network", "Player '{}' ({}) in flight, ignore worldport command.", GetPlayer()->GetName(), GetPlayer()->GetGUID().ToString());
1113 return;
1114 }
1115
1116 LOG_DEBUG("network", "CMSG_WORLD_TELEPORT: Player = {}, Time = {}, map = {}, x = {}, y = {}, z = {}, o = {}", GetPlayer()->GetName(), time, mapid, PositionX, PositionY, PositionZ, Orientation);
1117
1119 GetPlayer()->TeleportTo(mapid, PositionX, PositionY, PositionZ, Orientation);
1120 else
1122}

References GetPlayer(), GetSecurity(), AccountMgr::IsAdminAccount(), LANG_PERMISSION_DENIED, LOG_DEBUG, ChatHandler::SendNotification(), and Player::TeleportTo().

Referenced by OpcodeTable::Initialize().

◆ HandleWrapItemOpcode()

void WorldSession::HandleWrapItemOpcode ( WorldPacket recvPacket)
1269{
1270 LOG_DEBUG("network", "Received opcode CMSG_WRAP_ITEM");
1271
1272 uint8 gift_bag, gift_slot, item_bag, item_slot;
1273
1274 recvData >> gift_bag >> gift_slot; // paper
1275 recvData >> item_bag >> item_slot; // item
1276
1277 LOG_DEBUG("network", "WRAP: receive gift_bag = {}, gift_slot = {}, item_bag = {}, item_slot = {}", gift_bag, gift_slot, item_bag, item_slot);
1278
1279 Item* gift = _player->GetItemByPos(gift_bag, gift_slot);
1280 if (!gift)
1281 {
1283 return;
1284 }
1285
1286 if (!(gift->GetTemplate()->HasFlag(ITEM_FLAG_IS_WRAPPER))) // cheating: non-wrapper wrapper
1287 {
1289 return;
1290 }
1291
1292 Item* item = _player->GetItemByPos(item_bag, item_slot);
1293
1294 if (!item)
1295 {
1297 return;
1298 }
1299
1300 // xinef: do not allow to wrap removed items, just in case
1301 if (item->GetState() == ITEM_REMOVED)
1302 {
1304 return;
1305 }
1306
1307 if (item == gift) // not possable with pacjket from real client
1308 {
1310 return;
1311 }
1312
1313 if (item->IsEquipped())
1314 {
1316 return;
1317 }
1318
1319 if (item->GetGuidValue(ITEM_FIELD_GIFTCREATOR)) // HasFlag(ITEM_FIELD_FLAGS, ITEM_FLAGS_WRAPPED);
1320 {
1322 return;
1323 }
1324
1325 if (item->IsBag())
1326 {
1328 return;
1329 }
1330
1331 if (item->IsSoulBound())
1332 {
1334 return;
1335 }
1336
1337 if (item->GetMaxStackCount() != 1)
1338 {
1340 return;
1341 }
1342
1343 // maybe not correct check (it is better than nothing)
1344 if (item->GetTemplate()->MaxCount > 0)
1345 {
1347 return;
1348 }
1349
1350 if (item->GetTemplate()->Duration > 0)
1351 {
1353 return;
1354 }
1355
1356 CharacterDatabaseTransaction trans = CharacterDatabase.BeginTransaction();
1357
1359 stmt->SetData(0, item->GetOwnerGUID().GetCounter());
1360 stmt->SetData(1, item->GetGUID().GetCounter());
1361 stmt->SetData(2, item->GetEntry());
1362 stmt->SetData(3, item->GetUInt32Value(ITEM_FIELD_FLAGS));
1363 trans->Append(stmt);
1364
1365 item->SetEntry(gift->GetEntry());
1366
1367 switch (item->GetEntry())
1368 {
1369 case 5042:
1370 item->SetEntry(5043);
1371 break;
1372 case 5048:
1373 item->SetEntry(5044);
1374 break;
1375 case 17303:
1376 item->SetEntry(17302);
1377 break;
1378 case 17304:
1379 item->SetEntry(17305);
1380 break;
1381 case 17307:
1382 item->SetEntry(17308);
1383 break;
1384 case 21830:
1385 item->SetEntry(21831);
1386 break;
1387 }
1391
1392 // after save it will be impossible to remove the item from the queue
1394
1395 CharacterDatabase.CommitTransaction(trans);
1396
1397 uint32 count = 1;
1398 _player->DestroyItemCount(gift, count, true);
1399}
@ ITEM_FIELD_FLAG_WRAPPED
Definition: ItemTemplate.h:112
@ ITEM_FLAG_IS_WRAPPER
Definition: ItemTemplate.h:156
@ EQUIP_ERR_BAGS_CANT_BE_WRAPPED
Definition: Item.h:95
@ EQUIP_ERR_STACKABLE_CANT_BE_WRAPPED
Definition: Item.h:90
@ EQUIP_ERR_UNIQUE_CANT_BE_WRAPPED
Definition: Item.h:94
@ EQUIP_ERR_WRAPPED_CANT_BE_WRAPPED
Definition: Item.h:92
@ EQUIP_ERR_BOUND_CANT_BE_WRAPPED
Definition: Item.h:93
@ EQUIP_ERR_EQUIPPED_CANT_BE_WRAPPED
Definition: Item.h:91
@ ITEM_REMOVED
Definition: Item.h:212
@ CHAR_INS_CHAR_GIFT
Definition: CharacterDatabase.h:378

References _player, CHAR_INS_CHAR_GIFT, CharacterDatabase, Player::DestroyItemCount(), ItemTemplate::Duration, EQUIP_ERR_BAGS_CANT_BE_WRAPPED, EQUIP_ERR_BOUND_CANT_BE_WRAPPED, EQUIP_ERR_EQUIPPED_CANT_BE_WRAPPED, EQUIP_ERR_ITEM_NOT_FOUND, EQUIP_ERR_STACKABLE_CANT_BE_WRAPPED, EQUIP_ERR_UNIQUE_CANT_BE_WRAPPED, EQUIP_ERR_WRAPPED_CANT_BE_WRAPPED, ObjectGuid::GetCounter(), Object::GetEntry(), Object::GetGUID(), Object::GetGuidValue(), Player::GetItemByPos(), Item::GetMaxStackCount(), Item::GetOwnerGUID(), Item::GetState(), Item::GetTemplate(), Object::GetUInt32Value(), ItemTemplate::HasFlag(), Item::IsBag(), Item::IsEquipped(), Item::IsSoulBound(), ITEM_CHANGED, ITEM_FIELD_FLAG_WRAPPED, ITEM_FIELD_FLAGS, ITEM_FIELD_GIFTCREATOR, ITEM_FLAG_IS_WRAPPER, ITEM_REMOVED, LOG_DEBUG, ItemTemplate::MaxCount, Player::SaveInventoryAndGoldToDB(), Player::SendEquipError(), PreparedStatementBase::SetData(), Object::SetEntry(), Object::SetGuidValue(), Item::SetState(), and Object::SetUInt32Value().

Referenced by OpcodeTable::Initialize().

◆ HandleZoneUpdateOpcode()

void WorldSession::HandleZoneUpdateOpcode ( WorldPacket recvPacket)
523{
524 uint32 newZone;
525 recv_data >> newZone;
526
527 LOG_DEBUG("network", "WORLD: Recvd ZONE_UPDATE: {}", newZone);
528
529 // use server side data, but only after update the player position. See Player::UpdatePosition().
531
532 //GetPlayer()->SendInitWorldStates(true, newZone);
533}
void SetNeedZoneUpdate(bool needUpdate)
Definition: Player.h:1842

References GetPlayer(), LOG_DEBUG, and Player::SetNeedZoneUpdate().

Referenced by OpcodeTable::Initialize().

◆ InitializeSession()

void WorldSession::InitializeSession ( )
1663{
1664 uint32 cacheVersion = sWorld->getIntConfig(CONFIG_CLIENTCACHE_VERSION);
1665 sScriptMgr->OnBeforeFinalizePlayerWorldSession(cacheVersion);
1666
1667 std::shared_ptr<AccountInfoQueryHolderPerRealm> realmHolder = std::make_shared<AccountInfoQueryHolderPerRealm>();
1668 if (!realmHolder->Initialize(GetAccountId()))
1669 {
1671 return;
1672 }
1673
1674 AddQueryHolderCallback(CharacterDatabase.DelayQueryHolder(realmHolder)).AfterComplete([this, cacheVersion](SQLQueryHolderBase const& holder)
1675 {
1676 InitializeSessionCallback(static_cast<AccountInfoQueryHolderPerRealm const&>(holder), cacheVersion);
1677 });
1678}
@ CONFIG_CLIENTCACHE_VERSION
Definition: IWorld.h:345
@ AUTH_SYSTEM_ERROR
Definition: SharedDefines.h:3340
Definition: WorldSession.cpp:1634
void InitializeSessionCallback(CharacterDatabaseQueryHolder const &realmHolder, uint32 clientCacheVersion)
Definition: WorldSession.cpp:1680
void SendAuthResponse(uint8 code, bool shortForm, uint32 queuePos=0)
Definition: AuthHandler.cpp:22

References AddQueryHolderCallback(), SQLQueryHolderCallback::AfterComplete(), AUTH_SYSTEM_ERROR, CharacterDatabase, CONFIG_CLIENTCACHE_VERSION, GetAccountId(), InitializeSessionCallback(), SendAuthResponse(), sScriptMgr, and sWorld.

Referenced by World::AddSession_(), and World::RemoveQueuedPlayer().

◆ InitializeSessionCallback()

void WorldSession::InitializeSessionCallback ( CharacterDatabaseQueryHolder const &  realmHolder,
uint32  clientCacheVersion 
)
1681{
1683 LoadTutorialsData(realmHolder.GetPreparedResult(AccountInfoQueryHolderPerRealm::TUTORIALS));
1684
1685 if (!m_inQueue)
1686 {
1688 }
1689 else
1690 {
1692 }
1693
1694 SetInQueue(false);
1695 ResetTimeOutTime(false);
1696
1698 SendClientCacheVersion(clientCacheVersion);
1700}
@ AUTH_OK
Definition: SharedDefines.h:3335
@ TUTORIALS
Definition: WorldSession.cpp:1639
@ GLOBAL_ACCOUNT_DATA
Definition: WorldSession.cpp:1638
void LoadTutorialsData(PreparedQueryResult result)
Definition: WorldSession.cpp:917
void SendClientCacheVersion(uint32 version)
Definition: AuthHandler.cpp:40
void SendAuthWaitQueue(uint32 position)
Handle the authentication waiting queue (to be completed)
Definition: WorldSession.cpp:827
void SendAddonsInfo()
Definition: WorldSession.cpp:1193
void SetInQueue(bool state)
Session in auth.queue currently.
Definition: WorldSession.h:382
void SendTutorialsData()
Definition: WorldSession.cpp:932

References AUTH_OK, SQLQueryHolderBase::GetPreparedResult(), AccountInfoQueryHolderPerRealm::GLOBAL_ACCOUNT_DATA, GLOBAL_CACHE_MASK, LoadAccountData(), LoadTutorialsData(), m_inQueue, ResetTimeOutTime(), SendAddonsInfo(), SendAuthResponse(), SendAuthWaitQueue(), SendClientCacheVersion(), SendTutorialsData(), SetInQueue(), and AccountInfoQueryHolderPerRealm::TUTORIALS.

Referenced by InitializeSession().

◆ InitWarden()

void WorldSession::InitWarden ( SessionKey const &  k,
std::string const &  os 
)
1288{
1289 if (os == "Win")
1290 {
1291 _warden = std::make_unique<WardenWin>();
1292 _warden->Init(this, k);
1293 }
1294 else if (os == "OSX")
1295 {
1296 // Disabled as it is causing the client to crash
1297 // _warden = new WardenMac();
1298 // _warden->Init(this, k);
1299 }
1300}

References _warden.

Referenced by WorldSocket::HandleAuthSessionCallback().

◆ IsARecruiter()

bool WorldSession::IsARecruiter ( ) const
inline

◆ IsConnectionIdle()

bool WorldSession::IsConnectionIdle ( ) const
inline
521 {
522 return (m_timeOutTime <= 0 && !m_inQueue);
523 }

References m_inQueue, and m_timeOutTime.

Referenced by Update().

◆ IsGMAccount()

◆ IsKicked()

bool WorldSession::IsKicked ( ) const
inline
1069{ return _kicked; }

References _kicked.

Referenced by HandleSocketClosed(), and World::UpdateSessions().

◆ IsLegitCharacterForAccount()

bool WorldSession::IsLegitCharacterForAccount ( ObjectGuid  guid)
inlineprivate
1135 {
1136 return _legitCharacters.find(guid) != _legitCharacters.end();
1137 }

References _legitCharacters.

Referenced by HandleCharCustomize(), HandleCharFactionOrRaceChange(), and HandlePlayerLoginOpcode().

◆ isLogingOut()

bool WorldSession::isLogingOut ( ) const
inline

Is the user engaged in a log out process?

385{ return _logoutTime || m_playerLogout; }

References _logoutTime, and m_playerLogout.

Referenced by HandleInitiateTradeOpcode(), and Player::SaveToDB().

◆ IsSocketClosed()

bool WorldSession::IsSocketClosed ( ) const
538{
539 return !m_Socket || !m_Socket->IsOpen();
540}

References m_Socket.

Referenced by Group::ResetMaxEnchantingLevel().

◆ KickPlayer() [1/2]

◆ KickPlayer() [2/2]

void WorldSession::KickPlayer ( std::string const &  reason,
bool  setKicked = true 
)

Kick a player out of the World.

752{
753 if (m_Socket)
754 {
755 LOG_INFO("network.kick", "Account: {} Character: '{}' {} kicked with reason: {}", GetAccountId(), _player ? _player->GetName() : "<none>",
756 _player ? _player->GetGUID().ToString() : "", reason);
757
758 m_Socket->CloseSocket();
759 }
760
761 if (setKicked)
762 SetKicked(true); // pussywizard: the session won't be left ingame for 60 seconds and to also kick offline session
763}
void SetKicked(bool val)
Definition: WorldSession.h:1070

References _player, GetAccountId(), Object::GetGUID(), WorldObject::GetName(), LOG_INFO, m_Socket, SetKicked(), and ObjectGuid::ToString().

◆ LoadAccountData()

void WorldSession::LoadAccountData ( PreparedQueryResult  result,
uint32  mask 
)
846{
847 for (uint32 i = 0; i < NUM_ACCOUNT_DATA_TYPES; ++i)
848 if (mask & (1 << i))
850
851 if (!result)
852 return;
853
854 do
855 {
856 Field* fields = result->Fetch();
857 uint32 type = fields[0].Get<uint8>();
858 if (type >= NUM_ACCOUNT_DATA_TYPES)
859 {
860 LOG_ERROR("network", "Table `{}` have invalid account data type ({}), ignore.", mask == GLOBAL_CACHE_MASK ? "account_data" : "character_account_data", type);
861 continue;
862 }
863
864 if ((mask & (1 << type)) == 0)
865 {
866 LOG_ERROR("network", "Table `{}` have non appropriate for table account data type ({}), ignore.", mask == GLOBAL_CACHE_MASK ? "account_data" : "character_account_data", type);
867 continue;
868 }
869
870 m_accountData[type].Time = time_t(fields[1].Get<uint32>());
871 m_accountData[type].Data = fields[2].Get<std::string>();
872 } while (result->NextRow());
873}

References AccountData::Data, Field::Get(), GLOBAL_CACHE_MASK, LOG_ERROR, m_accountData, NUM_ACCOUNT_DATA_TYPES, and AccountData::Time.

Referenced by HandlePlayerLoginFromDB(), and InitializeSessionCallback().

◆ LoadTutorialsData()

void WorldSession::LoadTutorialsData ( PreparedQueryResult  result)
918{
919 memset(m_Tutorials, 0, sizeof(uint32) * MAX_ACCOUNT_TUTORIAL_VALUES);
920
921 if (result)
922 {
923 for (uint8 i = 0; i < MAX_ACCOUNT_TUTORIAL_VALUES; ++i)
924 {
925 m_Tutorials[i] = (*result)[i].Get<uint32>();
926 }
927 }
928
929 m_TutorialsChanged = false;
930}

References m_Tutorials, m_TutorialsChanged, and MAX_ACCOUNT_TUTORIAL_VALUES.

Referenced by InitializeSessionCallback().

◆ LogoutPlayer()

void WorldSession::LogoutPlayer ( bool  save)

Log the player out

Call script hook before other logout events

  • If the player just died before logging out, make him appear as a ghost
  • If the player is in a guild, update the guild roster and broadcast a logout message to other guild members
  • Remove pet
  • If the player is in a group and LeaveGroupOnLogout is enabled or if the player is invited to a group, remove him. If the group is then only 1 person, disband the group.
  • empty buyback items and save the player in the database
  • Leave all channels before player delete...

Send update to group and reset stored max enchanting level

Broadcast a logout message to the player's friends

Call script hook before deletion

Remove the player from the world

Send the 'logout complete' packet to the client Client will respond by sending 3x CMSG_CANCEL_TRADE, which we currently dont handle

Since each account can only have one online character at any given time, ensure all characters for active account are marked as offline

574{
575 // finish pending transfers before starting the logout
578
579 m_playerLogout = true;
580 m_playerSave = save;
581
582 if (_player)
583 {
585 sScriptMgr->OnBeforePlayerLogout(_player);
586
587 if (ObjectGuid lguid = _player->GetLootGUID())
588 DoLootRelease(lguid);
589
591 //FIXME: logout must be delayed in case lost connection with client in time of combat
592 if (_player->GetDeathTimer())
593 {
597 }
599 {
600 // this will kill character by SPELL_AURA_SPIRIT_OF_REDEMPTION
605 }
606 else if (_player->HasPendingBind())
607 {
609 _player->SetPendingBind(0, 0);
610 }
611
612 // pussywizard: leave whole bg on logout (character stays ingame when necessary)
613 // pussywizard: GetBattleground() checked inside
615
616 // pussywizard: checked first time
619
620 sOutdoorPvPMgr->HandlePlayerLeaveZone(_player, _player->GetZoneId());
621
622 // pussywizard: remove from battleground queues on logout
623 for (int i = 0; i < PLAYER_MAX_BATTLEGROUND_QUEUES; ++i)
625 {
626 // track if player logs out after invited to join BG
628 {
630 {
632 stmt->SetData(0, _player->GetGUID().GetCounter());
634 CharacterDatabase.Execute(stmt);
635 }
636
637 sScriptMgr->OnBattlegroundDesertion(_player, BG_DESERTION_TYPE_INVITE_LOGOUT);
638 }
639
640 if (bgQueueTypeId >= BATTLEGROUND_QUEUE_2v2 && bgQueueTypeId < MAX_BATTLEGROUND_QUEUE_TYPES && _player->IsInvitedForBattlegroundQueueType(bgQueueTypeId))
641 sScriptMgr->OnBattlegroundDesertion(_player, ARENA_DESERTION_TYPE_INVITE_LOGOUT);
642
643 _player->RemoveBattlegroundQueueId(bgQueueTypeId);
644 sBattlegroundMgr->GetBattlegroundQueue(bgQueueTypeId).RemovePlayer(_player->GetGUID(), true);
645 }
646
648 if (Guild* guild = sGuildMgr->GetGuildById(_player->GetGuildId()))
649 guild->HandleMemberLogout(this);
650
653
654 // pussywizard: on logout remove auras that are removed at map change (before saving to db)
655 // there are some positive auras from boss encounters that can be kept by logging out and logging in after boss is dead, and may be used on next bosses
657
659 if (!_player->GetGroup() || sWorld->getBoolConfig(CONFIG_LEAVE_GROUP_ON_LOGOUT))
661
662 // remove player from the group if he is:
663 // a) in group; b) not in raid group; c) logging out normally (not being kicked or disconnected) d) LeaveGroupOnLogout is enabled
666
667 // pussywizard: checked second time after being removed from a group
670
671 // Repop at GraveYard or other player far teleport will prevent saving player because of not present map
672 // Teleport player immediately for correct player save
675
677 // some save parts only correctly work in case player present in map/player_lists (pets, etc)
678 if (save)
679 {
680 uint32 eslot;
681 for (int j = BUYBACK_SLOT_START; j < BUYBACK_SLOT_END; ++j)
682 {
683 eslot = j - BUYBACK_SLOT_START;
687 }
688 _player->SaveToDB(false, true);
689 }
690
693
695 if (_player->GetGroup())
696 {
699
701 {
702 Map::PlayerList const &playerList = _player->GetMap()->GetPlayers();
703 if (playerList.IsEmpty())
705 }
706 }
707
709 sSocialMgr->SendFriendStatus(_player, FRIEND_OFFLINE, _player->GetGUID(), true);
710 sSocialMgr->RemovePlayerSocial(_player->GetGUID());
711
713 sScriptMgr->OnPlayerLogout(_player);
714
715 METRIC_EVENT("player_events", "Logout", _player->GetName());
716
717 LOG_INFO("entities.player", "Account: {} (IP: {}) Logout Character:[{}] ({}) Level: {}",
719
721 // the player may not be in the world when logging out
722 // e.g if he got disconnected during a transfer to another map
723 // calls to GetMap in this case may cause crashes
725 if (Map* _map = _player->FindMap())
726 {
727 _map->RemovePlayerFromMap(_player, true);
728 _map->AfterPlayerUnlinkFromMap();
729 }
730
731 SetPlayer(nullptr); // pointer already deleted
732
736 LOG_DEBUG("network", "SESSION: Sent SMSG_LOGOUT_COMPLETE Message");
737
740 stmt->SetData(0, GetAccountId());
741 CharacterDatabase.Execute(stmt);
742 }
743
744 m_playerLogout = false;
745 m_playerSave = false;
748}
@ ARENA_DESERTION_TYPE_INVITE_LOGOUT
Definition: Battleground.h:59
@ BG_DESERTION_TYPE_INVITE_LOGOUT
Definition: Battleground.h:55
#define sOutdoorPvPMgr
Definition: OutdoorPvPMgr.h:103
@ CONFIG_LEAVE_GROUP_ON_LOGOUT
Definition: IWorld.h:174
@ PLAYER_FIELD_VENDORBUYBACK_SLOT_1
Definition: UpdateFields.h:331
@ PLAYER_FIELD_BUYBACK_TIMESTAMP_1
Definition: UpdateFields.h:373
@ FRIEND_OFFLINE
Definition: SocialMgr.h:69
@ BUYBACK_SLOT_END
Definition: Player.h:725
@ SPELL_AURA_MOD_SHAPESHIFT
Definition: SpellAuraDefines.h:99
@ SPELL_AURA_SPIRIT_OF_REDEMPTION
Definition: SpellAuraDefines.h:239
@ AURA_INTERRUPT_FLAG_CHANGE_MAP
Definition: SpellDefines.h:62
@ CHAR_UPD_ACCOUNT_ONLINE
Definition: CharacterDatabase.h:280
void SaveToDB(bool create, bool logout)
Definition: PlayerStorage.cpp:7051
bool IsBeingTeleportedFar() const
Definition: Player.h:2074
void CleanupsBeforeDelete(bool finalCleanup=true) override
Definition: Player.cpp:460
uint32 GetDeathTimer() const
Definition: Player.h:2158
void ResetMaxEnchantingLevel()
Definition: Group.cpp:2215
bool IsRaidOrHeroicDungeon() const
Definition: Map.h:451
Definition: MapRefMgr.h:26
Definition: CharacterPackets.h:67

References _player, ARENA_DESERTION_TYPE_INVITE_LOGOUT, AURA_INTERRUPT_FLAG_CHANGE_MAP, BATTLEGROUND_QUEUE_2v2, BG_DESERTION_TYPE_INVITE_LOGOUT, Player::BuildPlayerRepop(), BUYBACK_SLOT_END, BUYBACK_SLOT_START, CHAR_INS_DESERTER_TRACK, CHAR_UPD_ACCOUNT_ONLINE, CharacterDatabase, Player::CleanupChannels(), Player::CleanupsBeforeDelete(), CONFIG_BATTLEGROUND_TRACK_DESERTERS, CONFIG_LEAVE_GROUP_ON_LOGOUT, HostileRefMgr::deleteReferences(), DoLootRelease(), ObjectGuid::Empty, WorldObject::FindMap(), FRIEND_OFFLINE, GetAccountId(), Player::GetBattlegroundQueueTypeId(), ObjectGuid::GetCounter(), Player::GetDeathTimer(), Player::GetGroup(), Object::GetGUID(), Player::GetGuildId(), Unit::getHostileRefMgr(), Unit::GetLevel(), Player::GetLootGUID(), WorldObject::GetMap(), WorldObject::GetName(), Map::GetPlayers(), GetRemoteAddress(), WorldObject::GetZoneId(), HandleMoveWorldportAck(), Unit::HasAuraType(), Player::HasPendingBind(), Player::IsBeingTeleportedFar(), Map::IsDungeon(), LinkedListHead::IsEmpty(), Player::IsGameMaster(), Player::IsInvitedForBattlegroundInstance(), Group::isLFGGroup(), Group::isRaidGroup(), Map::IsRaidOrHeroicDungeon(), Player::KillPlayer(), Player::LeaveBattleground(), LOG_DEBUG, LOG_INFO, Player::m_InstanceValid, m_playerLogout, m_playerRecentlyLogout, m_playerSave, m_Socket, METRIC_EVENT, PET_SAVE_AS_CURRENT, PLAYER_FIELD_BUYBACK_PRICE_1, PLAYER_FIELD_BUYBACK_TIMESTAMP_1, PLAYER_FIELD_VENDORBUYBACK_SLOT_1, PLAYER_MAX_BATTLEGROUND_QUEUES, Unit::RemoveAurasByType(), Unit::RemoveAurasWithInterruptFlags(), Player::RemoveBattlegroundQueueId(), Player::RemoveFromGroup(), Player::RemovePet(), Player::RepopAtGraveyard(), Group::ResetMaxEnchantingLevel(), Player::SaveToDB(), sBattlegroundMgr, SendPacket(), Group::SendUpdate(), PreparedStatementBase::SetData(), Object::SetGuidValue(), SetLogoutStartTime(), Player::SetPendingBind(), SetPlayer(), Unit::SetUInt32Value(), sGuildMgr, sOutdoorPvPMgr, SPELL_AURA_MOD_SHAPESHIFT, SPELL_AURA_SPIRIT_OF_REDEMPTION, sScriptMgr, sSocialMgr, sWorld, Player::TeleportToEntryPoint(), ObjectGuid::ToString(), and Player::UninviteFromGroup().

Referenced by AccountMgr::DeleteAccount(), HandleLogoutRequestOpcode(), Update(), and ~WorldSession().

◆ LogUnexpectedOpcode()

void WorldSession::LogUnexpectedOpcode ( WorldPacket packet,
char const *  status,
const char *  reason 
)
private

Logging helper for unexpected opcodes.

271{
272 LOG_ERROR("network.opcode", "Received unexpected opcode {} Status: {} Reason: {} from {}",
273 GetOpcodeNameForLogging(static_cast<OpcodeClient>(packet->GetOpcode())), status, reason, GetPlayerInfo());
274}

References WorldPacket::GetOpcode(), GetOpcodeNameForLogging(), GetPlayerInfo(), and LOG_ERROR.

Referenced by Update().

◆ LogUnprocessedTail()

void WorldSession::LogUnprocessedTail ( WorldPacket packet)
private

Logging helper for unexpected opcodes.

278{
279 if (!sLog->ShouldLog("network.opcode", LogLevel::LOG_LEVEL_TRACE) || packet->rpos() >= packet->wpos())
280 return;
281
282 LOG_TRACE("network.opcode", "Unprocessed tail data (read stop at {} from {}) Opcode {} from {}",
283 uint32(packet->rpos()), uint32(packet->wpos()), GetOpcodeNameForLogging(static_cast<OpcodeClient>(packet->GetOpcode())), GetPlayerInfo());
284
285 packet->print_storage();
286}
#define sLog
Definition: Log.h:125
#define LOG_TRACE(filterType__,...)
Definition: Log.h:172
void print_storage() const
Definition: ByteBuffer.cpp:152
std::size_t wpos() const
Definition: ByteBuffer.h:330
std::size_t rpos() const
Definition: ByteBuffer.h:317

References WorldPacket::GetOpcode(), GetOpcodeNameForLogging(), GetPlayerInfo(), LOG_TRACE, ByteBuffer::print_storage(), ByteBuffer::rpos(), sLog, and ByteBuffer::wpos().

Referenced by Update().

◆ moveItems()

void WorldSession::moveItems ( Item myItems[],
Item hisItems[] 
)
private
135{
136 Player* trader = _player->GetTrader();
137 if (!trader)
138 return;
139
140 for (uint8 i = 0; i < TRADE_SLOT_TRADED_COUNT; ++i)
141 {
142 ItemPosCountVec traderDst;
143 ItemPosCountVec playerDst;
144 bool traderCanTrade = (!myItems[i] || trader->CanStoreItem(NULL_BAG, NULL_SLOT, traderDst, myItems[i], false) == EQUIP_ERR_OK);
145 bool playerCanTrade = (!hisItems[i] || _player->CanStoreItem(NULL_BAG, NULL_SLOT, playerDst, hisItems[i], false) == EQUIP_ERR_OK);
146 if (traderCanTrade && playerCanTrade)
147 {
148 // Ok, if trade item exists and can be stored
149 // If we trade in both directions we had to check, if the trade will work before we actually do it
150 // A roll back is not possible after we stored it
151 if (myItems[i])
152 {
153 // logging
154 LOG_DEBUG("network", "partner storing: {}", myItems[i]->GetGUID().ToString());
155
156 // adjust time (depends on /played)
157 if (myItems[i]->IsBOPTradable())
159 // store
160 trader->MoveItemToInventory(traderDst, myItems[i], true, true);
161 }
162 if (hisItems[i])
163 {
164 // logging
165 LOG_DEBUG("network", "player storing: {}", hisItems[i]->GetGUID().ToString());
166
167 // adjust time (depends on /played)
168 if (hisItems[i]->IsBOPTradable())
170 // store
171 _player->MoveItemToInventory(playerDst, hisItems[i], true, true);
172 }
173 }
174 else
175 {
176 // in case of fatal error log error message
177 // return the already removed items to the original owner
178 if (myItems[i])
179 {
180 if (!traderCanTrade)
181 LOG_ERROR("network.opcode", "trader can't store item: {}", myItems[i]->GetGUID().ToString());
182 if (_player->CanStoreItem(NULL_BAG, NULL_SLOT, playerDst, myItems[i], false) == EQUIP_ERR_OK)
183 _player->MoveItemToInventory(playerDst, myItems[i], true, true);
184 else
185 LOG_ERROR("network.opcode", "player can't take item back: {}", myItems[i]->GetGUID().ToString());
186 }
187 // return the already removed items to the original owner
188 if (hisItems[i])
189 {
190 if (!playerCanTrade)
191 LOG_ERROR("network.opcode", "player can't store item: {}", hisItems[i]->GetGUID().ToString());
192 if (trader->CanStoreItem(NULL_BAG, NULL_SLOT, traderDst, hisItems[i], false) == EQUIP_ERR_OK)
193 trader->MoveItemToInventory(traderDst, hisItems[i], true, true);
194 else
195 LOG_ERROR("network.opcode", "trader can't take item back: {}", hisItems[i]->GetGUID().ToString());
196 }
197 }
198 }
199}
@ ITEM_FIELD_CREATE_PLAYED_TIME
Definition: UpdateFields.h:71
Player * GetTrader() const
Definition: Player.h:1369

References _player, Player::CanStoreItem(), EQUIP_ERR_OK, Player::GetTotalPlayedTime(), Player::GetTrader(), Object::GetUInt32Value(), ITEM_FIELD_CREATE_PLAYED_TIME, LOG_DEBUG, LOG_ERROR, Player::MoveItemToInventory(), NULL_BAG, NULL_SLOT, Object::SetUInt32Value(), and TRADE_SLOT_TRADED_COUNT.

Referenced by HandleAcceptTradeOpcode().

◆ operator=()

WorldSession & WorldSession::operator= ( WorldSession const &  right)
privatedelete

◆ PlayerLoading()

◆ PlayerLogout()

◆ PlayerLogoutWithSave()

bool WorldSession::PlayerLogoutWithSave ( ) const
inline
340{ return m_playerLogout && m_playerSave; }

References m_playerLogout, and m_playerSave.

◆ PlayerRecentlyLoggedOut()

bool WorldSession::PlayerRecentlyLoggedOut ( ) const
inline
339{ return m_playerRecentlyLogout; }

References m_playerRecentlyLogout.

Referenced by SendCancelTrade().

◆ ProcessQueryCallbacks()

void WorldSession::ProcessQueryCallbacks ( )
private

◆ QueuePacket()

void WorldSession::QueuePacket ( WorldPacket new_packet)

Add an incoming packet to the queue.

265{
266 _recvQueue.add(new_packet);
267}
void add(const T &item)
Adds an item to the queue.
Definition: LockedQueue.h:45

References _recvQueue, and LockedQueue< T, StorageType >::add().

Referenced by WorldSocket::ReadDataHandler().

◆ ReadAddonsInfo()

void WorldSession::ReadAddonsInfo ( ByteBuffer data)
Todo:
: Find out when to not use CRC/pubkey, and other possible states.
1112{
1113 if (data.rpos() + 4 > data.size())
1114 return;
1115
1116 uint32 size;
1117 data >> size;
1118
1119 if (!size)
1120 return;
1121
1122 if (size > 0xFFFFF)
1123 {
1124 LOG_ERROR("network", "WorldSession::ReadAddonsInfo addon info too big, size {}", size);
1125 return;
1126 }
1127
1128 uLongf uSize = size;
1129
1130 uint32 pos = data.rpos();
1131
1132 ByteBuffer addonInfo;
1133 addonInfo.resize(size);
1134
1135 if (uncompress(addonInfo.contents(), &uSize, data.contents() + pos, data.size() - pos) == Z_OK)
1136 {
1137 uint32 addonsCount;
1138 addonInfo >> addonsCount; // addons count
1139
1140 for (uint32 i = 0; i < addonsCount; ++i)
1141 {
1142 std::string addonName;
1143 uint8 enabled;
1144 uint32 crc, unk1;
1145
1146 // check next addon data format correctness
1147 if (addonInfo.rpos() + 1 > addonInfo.size())
1148 return;
1149
1150 addonInfo >> addonName;
1151
1152 addonInfo >> enabled >> crc >> unk1;
1153
1154 LOG_DEBUG("network", "ADDON: Name: {}, Enabled: 0x{:x}, CRC: 0x{:x}, Unknown2: 0x{:x}", addonName, enabled, crc, unk1);
1155
1156 AddonInfo addon(addonName, enabled, crc, 2, true);
1157
1158 SavedAddon const* savedAddon = AddonMgr::GetAddonInfo(addonName);
1159 if (savedAddon)
1160 {
1161 bool match = true;
1162
1163 if (addon.CRC != savedAddon->CRC)
1164 match = false;
1165
1166 if (!match)
1167 LOG_DEBUG("network", "ADDON: {} was known, but didn't match known CRC (0x{:x})!", addon.Name, savedAddon->CRC);
1168 else
1169 LOG_DEBUG("network", "ADDON: {} was known, CRC is correct (0x{:x})", addon.Name, savedAddon->CRC);
1170 }
1171 else
1172 {
1173 AddonMgr::SaveAddon(addon);
1174
1175 LOG_DEBUG("network", "ADDON: {} (0x{:x}) was not known, saving...", addon.Name, addon.CRC);
1176 }
1177
1179 m_addonsList.push_back(addon);
1180 }
1181
1182 uint32 currentTime;
1183 addonInfo >> currentTime;
1184 LOG_DEBUG("network", "ADDON: CurrentTime: {}", currentTime);
1185
1186 if (addonInfo.rpos() != addonInfo.size())
1187 LOG_DEBUG("network", "packet under-read!");
1188 }
1189 else
1190 LOG_ERROR("network", "Addon packet uncompress error!");
1191}
SavedAddon const * GetAddonInfo(const std::string &name)
Definition: AddonMgr.cpp:109
void SaveAddon(AddonInfo const &addon)
Definition: AddonMgr.cpp:95
Definition: AddonMgr.h:28
Definition: AddonMgr.h:40
uint32 CRC
Definition: AddonMgr.h:47
AddonsList m_addonsList
Definition: WorldSession.h:1172

References ByteBuffer::contents(), AddonInfo::CRC, SavedAddon::CRC, AddonMgr::GetAddonInfo(), LOG_DEBUG, LOG_ERROR, m_addonsList, AddonInfo::Name, ByteBuffer::resize(), ByteBuffer::rpos(), AddonMgr::SaveAddon(), and ByteBuffer::size().

Referenced by WorldSocket::HandleAuthSessionCallback().

◆ ReadMovementInfo()

void WorldSession::ReadMovementInfo ( WorldPacket data,
MovementInfo mi 
)

Anti-cheat checks. Please keep them in seperate if () blocks to maintain a clear overview. Might be subject to latency, so just remove improper flags.

This must be a packet spoofing attempt. MOVEMENTFLAG_ROOT sent from the client is not valid in conjunction with any of the moving movement flags such as MOVEMENTFLAG_FORWARD. It will freeze clients that receive this player's movement info.

Cannot hover without SPELL_AURA_HOVER

Cannot ascend and descend at the same time

Cannot move left and right at the same time

Cannot strafe left and right at the same time

Cannot pitch up and down at the same time

Cannot move forwards and backwards at the same time

Cannot walk on water without SPELL_AURA_WATER_WALK

Cannot feather fall without SPELL_AURA_FEATHER_FALL

Cannot fly if no fly auras present. Exception is being a GM. Note that we check for account level instead of Player::IsGameMaster() because in some situations it may be feasable to use .gm fly on as a GM without having .gm on, e.g. aerial combat.

Cannot fly and fall at the same time

960{
961 data >> mi->flags;
962 data >> mi->flags2;
963 data >> mi->time;
964 data >> mi->pos.PositionXYZOStream();
965
967 {
968 data >> mi->transport.guid.ReadAsPacked();
969
970 data >> mi->transport.pos.PositionXYZOStream();
971 data >> mi->transport.time;
972 data >> mi->transport.seat;
973
975 data >> mi->transport.time2;
976 }
977
979 data >> mi->pitch;
980
981 data >> mi->fallTime;
982
984 {
985 data >> mi->jump.zspeed;
986 data >> mi->jump.sinAngle;
987 data >> mi->jump.cosAngle;
988 data >> mi->jump.xyspeed;
989 }
990
992 data >> mi->splineElevation;
993
996#ifdef ACORE_DEBUG
997#define REMOVE_VIOLATING_FLAGS(check, maskToRemove) \
998 { \
999 if (check) \
1000 { \
1001 LOG_DEBUG("entities.unit", "WorldSession::ReadMovementInfo: Violation of MovementFlags found ({}). " \
1002 "MovementFlags: {}, MovementFlags2: {} for player {}. Mask {} will be removed.", \
1003 STRINGIZE(check), mi->GetMovementFlags(), mi->GetExtraMovementFlags(), GetPlayer()->GetGUID().ToString(), maskToRemove); \
1004 mi->RemoveMovementFlag((maskToRemove)); \
1005 } \
1006 }
1007#else
1008#define REMOVE_VIOLATING_FLAGS(check, maskToRemove) \
1009 if (check) \
1010 mi->RemoveMovementFlag((maskToRemove));
1011#endif
1012
1019
1023
1027
1031
1035
1039
1043
1046 !GetPlayer()->HasAuraType(SPELL_AURA_WATER_WALK) &&
1047 !GetPlayer()->HasAuraType(SPELL_AURA_GHOST),
1049
1053
1062
1066
1068 (!GetPlayer()->movespline->Initialized() || GetPlayer()->movespline->Finalized()), MOVEMENTFLAG_SPLINE_ENABLED);
1069
1070#undef REMOVE_VIOLATING_FLAGS
1071}
#define REMOVE_VIOLATING_FLAGS(check, maskToRemove)
MovementFlags
Definition: UnitDefines.h:342
@ MOVEMENTFLAG_DESCENDING
Definition: UnitDefines.h:367
@ MOVEMENTFLAG_PITCH_DOWN
Definition: UnitDefines.h:351
@ MOVEMENTFLAG_PITCH_UP
Definition: UnitDefines.h:350
@ MOVEMENTFLAG_RIGHT
Definition: UnitDefines.h:349
@ MOVEMENTFLAG_SPLINE_ENABLED
Definition: UnitDefines.h:371
@ MOVEMENTFLAG_FORWARD
Definition: UnitDefines.h:344
@ MOVEMENTFLAG_STRAFE_LEFT
Definition: UnitDefines.h:346
@ MOVEMENTFLAG_BACKWARD
Definition: UnitDefines.h:345
@ MOVEMENTFLAG_WATERWALKING
Definition: UnitDefines.h:372
@ MOVEMENTFLAG_DISABLE_GRAVITY
Definition: UnitDefines.h:354
@ MOVEMENTFLAG_FLYING
Definition: UnitDefines.h:369
@ MOVEMENTFLAG_FALLING_SLOW
Definition: UnitDefines.h:373
@ MOVEMENTFLAG_ROOT
Definition: UnitDefines.h:355
@ MOVEMENTFLAG_LEFT
Definition: UnitDefines.h:348
@ MOVEMENTFLAG_STRAFE_RIGHT
Definition: UnitDefines.h:347
@ MOVEMENTFLAG_ASCENDING
Definition: UnitDefines.h:366
@ MOVEMENTFLAG_HOVER
Definition: UnitDefines.h:374
@ MOVEMENTFLAG_SPLINE_ELEVATION
Definition: UnitDefines.h:370
@ MOVEMENTFLAG2_ALWAYS_ALLOW_PITCHING
Definition: UnitDefines.h:405
@ MOVEMENTFLAG2_INTERPOLATED_MOVEMENT
Definition: UnitDefines.h:410
@ SPELL_AURA_FEATHER_FALL
Definition: SpellAuraDefines.h:168
@ SPELL_AURA_FLY
Definition: SpellAuraDefines.h:264
@ SPELL_AURA_GHOST
Definition: SpellAuraDefines.h:158
@ SPELL_AURA_WATER_WALK
Definition: SpellAuraDefines.h:167
@ SPELL_AURA_HOVER
Definition: SpellAuraDefines.h:169
@ SPELL_AURA_MOD_INCREASE_MOUNTED_FLIGHT_SPEED
Definition: SpellAuraDefines.h:270
struct MovementInfo::JumpInfo jump
uint16 flags2
Definition: Object.h:280
float splineElevation
Definition: Object.h:321
float pitch
Definition: Object.h:304
bool HasExtraMovementFlag(uint16 flag) const
Definition: Object.h:338
uint32 time2
Definition: Object.h:300
uint32 time
Definition: Object.h:299
float cosAngle
Definition: Object.h:317
float xyspeed
Definition: Object.h:317
float zspeed
Definition: Object.h:317
float sinAngle
Definition: Object.h:317
Position::PositionXYZOStreamer PositionXYZOStream()
Definition: Position.h:150

References MovementInfo::JumpInfo::cosAngle, MovementInfo::fallTime, MovementInfo::flags, MovementInfo::flags2, GetPlayer(), GetSecurity(), MovementInfo::TransportInfo::guid, Unit::HasAuraType(), MovementInfo::HasExtraMovementFlag(), MovementInfo::HasMovementFlag(), MovementInfo::jump, MOVEMENTFLAG2_ALWAYS_ALLOW_PITCHING, MOVEMENTFLAG2_INTERPOLATED_MOVEMENT, MOVEMENTFLAG_ASCENDING, MOVEMENTFLAG_BACKWARD, MOVEMENTFLAG_CAN_FLY, MOVEMENTFLAG_DESCENDING, MOVEMENTFLAG_DISABLE_GRAVITY, MOVEMENTFLAG_FALLING, MOVEMENTFLAG_FALLING_SLOW, MOVEMENTFLAG_FLYING, MOVEMENTFLAG_FORWARD, MOVEMENTFLAG_HOVER, MOVEMENTFLAG_LEFT, MOVEMENTFLAG_ONTRANSPORT, MOVEMENTFLAG_PITCH_DOWN, MOVEMENTFLAG_PITCH_UP, MOVEMENTFLAG_RIGHT, MOVEMENTFLAG_ROOT, MOVEMENTFLAG_SPLINE_ELEVATION, MOVEMENTFLAG_SPLINE_ENABLED, MOVEMENTFLAG_STRAFE_LEFT, MOVEMENTFLAG_STRAFE_RIGHT, MOVEMENTFLAG_SWIMMING, MOVEMENTFLAG_WATERWALKING, MovementInfo::pitch, MovementInfo::pos, MovementInfo::TransportInfo::pos, Position::PositionXYZOStream(), ObjectGuid::ReadAsPacked(), REMOVE_VIOLATING_FLAGS, MovementInfo::TransportInfo::seat, SEC_PLAYER, MovementInfo::JumpInfo::sinAngle, SPELL_AURA_FEATHER_FALL, SPELL_AURA_FLY, SPELL_AURA_GHOST, SPELL_AURA_HOVER, SPELL_AURA_MOD_INCREASE_MOUNTED_FLIGHT_SPEED, SPELL_AURA_WATER_WALK, MovementInfo::splineElevation, MovementInfo::time, MovementInfo::TransportInfo::time, MovementInfo::TransportInfo::time2, MovementInfo::transport, MovementInfo::JumpInfo::xyspeed, and MovementInfo::JumpInfo::zspeed.

Referenced by HandleChangeSeatsOnControlledVehicle(), HandleDismissControlledVehicle(), HandleForceSpeedChangeAck(), HandleMoveHoverAck(), HandleMoveKnockBackAck(), HandleMovementOpcodes(), HandleMoveNotActiveMover(), HandleMoveRootAck(), HandleMoveSetCanFlyAckOpcode(), HandleMoveSplineDoneOpcode(), HandleMoveUnRootAck(), and HandleMoveWaterWalkAck().

◆ recoveryItem()

bool WorldSession::recoveryItem ( Item pItem)
private
1689{
1690 if (sWorld->getBoolConfig(CONFIG_ITEMDELETE_METHOD)
1691 && pItem->GetTemplate()->Quality >= sWorld->getIntConfig(CONFIG_ITEMDELETE_QUALITY)
1692 && pItem->GetTemplate()->ItemLevel >= sWorld->getIntConfig(CONFIG_ITEMDELETE_ITEM_LEVEL))
1693 {
1695
1696 stmt->SetData(0, pItem->GetOwnerGUID().GetCounter());
1697 stmt->SetData(1, pItem->GetTemplate()->ItemId);
1698 stmt->SetData(2, pItem->GetCount());
1699
1700 CharacterDatabase.Query(stmt);
1701
1702 return true;
1703 }
1704
1705 return false;
1706}
@ CONFIG_ITEMDELETE_QUALITY
Definition: IWorld.h:386
@ CONFIG_ITEMDELETE_ITEM_LEVEL
Definition: IWorld.h:387
@ CONFIG_ITEMDELETE_METHOD
Definition: IWorld.h:160
@ CHAR_INS_RECOVERY_ITEM
Definition: CharacterDatabase.h:506

References CHAR_INS_RECOVERY_ITEM, CharacterDatabase, CONFIG_ITEMDELETE_ITEM_LEVEL, CONFIG_ITEMDELETE_METHOD, CONFIG_ITEMDELETE_QUALITY, Item::GetCount(), ObjectGuid::GetCounter(), Item::GetOwnerGUID(), Item::GetTemplate(), ItemTemplate::ItemId, ItemTemplate::ItemLevel, ItemTemplate::Quality, PreparedStatementBase::SetData(), and sWorld.

Referenced by HandleDestroyItemOpcode(), and HandleSellItemOpcode().

◆ ResetTimeOutTime()

void WorldSession::ResetTimeOutTime ( bool  onlyActive)
inline
514 {
515 if (GetPlayer())
517 else if (!onlyActive)
519 }
@ CONFIG_SOCKET_TIMEOUTTIME
Definition: IWorld.h:215
@ CONFIG_SOCKET_TIMEOUTTIME_ACTIVE
Definition: IWorld.h:381

References CONFIG_SOCKET_TIMEOUTTIME, CONFIG_SOCKET_TIMEOUTTIME_ACTIVE, GetPlayer(), m_timeOutTime, and sWorld.

Referenced by InitializeSessionCallback(), WorldSocket::ReadDataHandler(), World::RemoveQueuedPlayer(), and WorldSession().

◆ ResetTimeSync()

void WorldSession::ResetTimeSync ( )

◆ SaveTutorialsData()

void WorldSession::SaveTutorialsData ( CharacterDatabaseTransaction  trans)
941{
943 return;
944
946 stmt->SetData(0, GetAccountId());
947 bool hasTutorials = bool(CharacterDatabase.Query(stmt));
948
949 stmt = CharacterDatabase.GetPreparedStatement(hasTutorials ? CHAR_UPD_TUTORIALS : CHAR_INS_TUTORIALS);
950
951 for (uint8 i = 0; i < MAX_ACCOUNT_TUTORIAL_VALUES; ++i)
952 stmt->SetData(i, m_Tutorials[i]);
954 trans->Append(stmt);
955
956 m_TutorialsChanged = false;
957}
@ CHAR_INS_TUTORIALS
Definition: CharacterDatabase.h:207
@ CHAR_UPD_TUTORIALS
Definition: CharacterDatabase.h:208
@ CHAR_SEL_HAS_TUTORIALS
Definition: CharacterDatabase.h:206

References CHAR_INS_TUTORIALS, CHAR_SEL_HAS_TUTORIALS, CHAR_UPD_TUTORIALS, CharacterDatabase, GetAccountId(), m_Tutorials, m_TutorialsChanged, MAX_ACCOUNT_TUTORIAL_VALUES, and PreparedStatementBase::SetData().

Referenced by Player::SaveToDB().

◆ SendAccountDataTimes()

void WorldSession::SendAccountDataTimes ( uint32  mask)
906{
907 WorldPacket data(SMSG_ACCOUNT_DATA_TIMES, 4 + 1 + 4 + 8 * 4); // changed in WotLK
908 data << uint32(GameTime::GetGameTime().count()); // unix time of something
909 data << uint8(1);
910 data << uint32(mask); // type mask
911 for (uint32 i = 0; i < NUM_ACCOUNT_DATA_TYPES; ++i)
912 if (mask & (1 << i))
913 data << uint32(GetAccountData(AccountDataType(i))->Time);// also unix time
914 SendPacket(&data);
915}
@ SMSG_ACCOUNT_DATA_TIMES
Definition: Opcodes.h:551

References GetAccountData(), GameTime::GetGameTime(), NUM_ACCOUNT_DATA_TYPES, SendPacket(), and SMSG_ACCOUNT_DATA_TIMES.

Referenced by HandlePlayerLoginFromDB(), HandlePlayerLoginToCharInWorld(), and HandleReadyForAccountDataTimes().

◆ SendActivateTaxiReply()

void WorldSession::SendActivateTaxiReply ( ActivateTaxiReply  reply)
280{
281 GetPlayer()->SetCanTeleport(true);
283 data << uint32(reply);
284 SendPacket(&data);
285
286 LOG_DEBUG("network", "WORLD: Sent SMSG_ACTIVATETAXIREPLY");
287}
@ SMSG_ACTIVATETAXIREPLY
Definition: Opcodes.h:460

References GetPlayer(), LOG_DEBUG, SendPacket(), Player::SetCanTeleport(), and SMSG_ACTIVATETAXIREPLY.

Referenced by Player::ActivateTaxiPathTo(), HandleActivateTaxiExpressOpcode(), and HandleActivateTaxiOpcode().

◆ SendAddonsInfo()

void WorldSession::SendAddonsInfo ( )
Todo:
: Find out the meaning of this.
1194{
1195 uint8 addonPublicKey[256] =
1196 {
1197 0xC3, 0x5B, 0x50, 0x84, 0xB9, 0x3E, 0x32, 0x42, 0x8C, 0xD0, 0xC7, 0x48, 0xFA, 0x0E, 0x5D, 0x54,
1198 0x5A, 0xA3, 0x0E, 0x14, 0xBA, 0x9E, 0x0D, 0xB9, 0x5D, 0x8B, 0xEE, 0xB6, 0x84, 0x93, 0x45, 0x75,
1199 0xFF, 0x31, 0xFE, 0x2F, 0x64, 0x3F, 0x3D, 0x6D, 0x07, 0xD9, 0x44, 0x9B, 0x40, 0x85, 0x59, 0x34,
1200 0x4E, 0x10, 0xE1, 0xE7, 0x43, 0x69, 0xEF, 0x7C, 0x16, 0xFC, 0xB4, 0xED, 0x1B, 0x95, 0x28, 0xA8,
1201 0x23, 0x76, 0x51, 0x31, 0x57, 0x30, 0x2B, 0x79, 0x08, 0x50, 0x10, 0x1C, 0x4A, 0x1A, 0x2C, 0xC8,
1202 0x8B, 0x8F, 0x05, 0x2D, 0x22, 0x3D, 0xDB, 0x5A, 0x24, 0x7A, 0x0F, 0x13, 0x50, 0x37, 0x8F, 0x5A,
1203 0xCC, 0x9E, 0x04, 0x44, 0x0E, 0x87, 0x01, 0xD4, 0xA3, 0x15, 0x94, 0x16, 0x34, 0xC6, 0xC2, 0xC3,
1204 0xFB, 0x49, 0xFE, 0xE1, 0xF9, 0xDA, 0x8C, 0x50, 0x3C, 0xBE, 0x2C, 0xBB, 0x57, 0xED, 0x46, 0xB9,
1205 0xAD, 0x8B, 0xC6, 0xDF, 0x0E, 0xD6, 0x0F, 0xBE, 0x80, 0xB3, 0x8B, 0x1E, 0x77, 0xCF, 0xAD, 0x22,
1206 0xCF, 0xB7, 0x4B, 0xCF, 0xFB, 0xF0, 0x6B, 0x11, 0x45, 0x2D, 0x7A, 0x81, 0x18, 0xF2, 0x92, 0x7E,
1207 0x98, 0x56, 0x5D, 0x5E, 0x69, 0x72, 0x0A, 0x0D, 0x03, 0x0A, 0x85, 0xA2, 0x85, 0x9C, 0xCB, 0xFB,
1208 0x56, 0x6E, 0x8F, 0x44, 0xBB, 0x8F, 0x02, 0x22, 0x68, 0x63, 0x97, 0xBC, 0x85, 0xBA, 0xA8, 0xF7,
1209 0xB5, 0x40, 0x68, 0x3C, 0x77, 0x86, 0x6F, 0x4B, 0xD7, 0x88, 0xCA, 0x8A, 0xD7, 0xCE, 0x36, 0xF0,
1210 0x45, 0x6E, 0xD5, 0x64, 0x79, 0x0F, 0x17, 0xFC, 0x64, 0xDD, 0x10, 0x6F, 0xF3, 0xF5, 0xE0, 0xA6,
1211 0xC3, 0xFB, 0x1B, 0x8C, 0x29, 0xEF, 0x8E, 0xE5, 0x34, 0xCB, 0xD1, 0x2A, 0xCE, 0x79, 0xC3, 0x9A,
1212 0x0D, 0x36, 0xEA, 0x01, 0xE0, 0xAA, 0x91, 0x20, 0x54, 0xF0, 0x72, 0xD8, 0x1E, 0xC7, 0x89, 0xD2
1213 };
1214
1216
1217 for (AddonsList::iterator itr = m_addonsList.begin(); itr != m_addonsList.end(); ++itr)
1218 {
1219 data << uint8(itr->State);
1220
1221 uint8 crcpub = itr->UsePublicKeyOrCRC;
1222 data << uint8(crcpub);
1223 if (crcpub)
1224 {
1225 uint8 usepk = (itr->CRC != STANDARD_ADDON_CRC); // If addon is Standard addon CRC
1226 data << uint8(usepk);
1227 if (usepk) // if CRC is wrong, add public key (client need it)
1228 {
1229 LOG_DEBUG("network", "ADDON: CRC (0x{:x}) for addon {} is wrong (does not match expected 0x{:x}), sending pubkey", itr->CRC, itr->Name, STANDARD_ADDON_CRC);
1230 data.append(addonPublicKey, sizeof(addonPublicKey));
1231 }
1232
1233 data << uint32(0);
1234 }
1235
1236 uint8 unk3 = 0; // 0 is sent here
1237 data << uint8(unk3);
1238 if (unk3)
1239 {
1240 // String, length 256 (null terminated)
1241 data << uint8(0);
1242 }
1243 }
1244
1245 m_addonsList.clear();
1246
1248 data << uint32(bannedAddons->size());
1249 for (AddonMgr::BannedAddonList::const_iterator itr = bannedAddons->begin(); itr != bannedAddons->end(); ++itr)
1250 {
1251 data << uint32(itr->Id);
1252 data.append(itr->NameMD5);
1253 data.append(itr->VersionMD5);
1254 data << uint32(itr->Timestamp);
1255 data << uint32(1); // IsBanned
1256 }
1257
1258 SendPacket(&data);
1259}
#define STANDARD_ADDON_CRC
Definition: AddonMgr.h:58
@ SMSG_ADDON_INFO
Definition: Opcodes.h:781
std::list< BannedAddon > BannedAddonList
Definition: AddonMgr.h:66
BannedAddonList const * GetBannedAddons()
Definition: AddonMgr.cpp:122

References ByteBuffer::append(), AddonMgr::GetBannedAddons(), LOG_DEBUG, m_addonsList, SendPacket(), SMSG_ADDON_INFO, and STANDARD_ADDON_CRC.

Referenced by InitializeSessionCallback().

◆ SendAreaTriggerMessage() [1/2]

void WorldSession::SendAreaTriggerMessage ( const char *  Text,
  ... 
)
692{
693 va_list ap;
694 char szStr [1024];
695 szStr[0] = '\0';
696
697 va_start(ap, Text);
698 vsnprintf(szStr, 1024, Text, ap);
699 va_end(ap);
700
701 uint32 length = strlen(szStr) + 1;
702 WorldPacket data(SMSG_AREA_TRIGGER_MESSAGE, 4 + length);
703 data << length;
704 data << szStr;
705 SendPacket(&data);
706}
@ SMSG_AREA_TRIGGER_MESSAGE
Definition: Opcodes.h:726

References SendPacket(), and SMSG_AREA_TRIGGER_MESSAGE.

Referenced by BattlegroundAB::HandleAreaTrigger(), BattlegroundAV::HandleAreaTrigger(), send_commandscript::HandleSendMessageCommand(), MapMgr::PlayerCannotEnter(), and Player::Satisfy().

◆ SendAreaTriggerMessage() [2/2]

void WorldSession::SendAreaTriggerMessage ( uint32  entry,
  ... 
)
709{
710 char const* format = GetAcoreString(entry);
711 if (format)
712 {
713 va_list ap;
714 char szStr[1024];
715 szStr[0] = '\0';
716
717 va_start(ap, entry);
718 vsnprintf(szStr, 1024, format, ap);
719 va_end(ap);
720
721 uint32 length = strlen(szStr) + 1;
722 WorldPacket data(SMSG_AREA_TRIGGER_MESSAGE, 4 + length);
723 data << length;
724 data << szStr;
725 SendPacket(&data);
726 }
727}

References GetAcoreString(), SendPacket(), and SMSG_AREA_TRIGGER_MESSAGE.

◆ SendArenaTeamCommandResult()

void WorldSession::SendArenaTeamCommandResult ( uint32  team_action,
std::string const &  team,
std::string const &  player,
uint32  error_id = 0 
)
407{
408 WorldPacket data(SMSG_ARENA_TEAM_COMMAND_RESULT, 4 + team.length() + 1 + player.length() + 1 + 4);
409 data << uint32(teamAction);
410 data << team;
411 data << player;
412 data << uint32(errorId);
413 SendPacket(&data);
414}
@ SMSG_ARENA_TEAM_COMMAND_RESULT
Definition: Opcodes.h:871

References SendPacket(), and SMSG_ARENA_TEAM_COMMAND_RESULT.

Referenced by ArenaTeam::DelMember(), HandleArenaTeamAcceptOpcode(), HandleArenaTeamInviteOpcode(), HandleArenaTeamLeaderOpcode(), HandleArenaTeamLeaveOpcode(), HandleArenaTeamRemoveOpcode(), HandleOfferPetitionOpcode(), HandlePetitionBuyOpcode(), HandlePetitionRenameOpcode(), HandlePetitionSignOpcode(), and HandleTurnInPetitionOpcode().

◆ SendAttackStop()

void WorldSession::SendAttackStop ( Unit const *  enemy)
85{
86 WorldPacket data(SMSG_ATTACKSTOP, (8 + 8 + 4)); // we guess size
87 data << GetPlayer()->GetPackGUID();
88
89 if (enemy)
90 {
91 data << enemy->GetPackGUID(); // must be packed guid
92 data << (uint32)enemy->isDead();
93 }
94 SendPacket(&data);
95}
@ SMSG_ATTACKSTOP
Definition: Opcodes.h:354

References Object::GetPackGUID(), GetPlayer(), Unit::isDead(), SendPacket(), and SMSG_ATTACKSTOP.

Referenced by HandleAttackSwingOpcode().

◆ SendAuctionBidderNotification()

void WorldSession::SendAuctionBidderNotification ( uint32  location,
uint32  auctionId,
ObjectGuid  bidder,
uint32  bidSum,
uint32  diff,
uint32  item_template 
)
89{
91 data << uint32(location);
92 data << uint32(auctionId);
93 data << bidder;
94 data << uint32(bidSum);
95 data << uint32(diff);
96 data << uint32(item_template);
97 data << uint32(0);
98 SendPacket(&data);
99}
@ SMSG_AUCTION_BIDDER_NOTIFICATION
Definition: Opcodes.h:636

References SendPacket(), and SMSG_AUCTION_BIDDER_NOTIFICATION.

Referenced by AuctionHouseMgr::SendAuctionOutbiddedMail(), and AuctionHouseMgr::SendAuctionWonMail().

◆ SendAuctionCommandResult()

void WorldSession::SendAuctionCommandResult ( uint32  auctionId,
uint32  Action,
uint32  ErrorCode,
uint32  bidError = 0 
)
77{
79 data << auctionId;
80 data << Action;
81 data << ErrorCode;
82 if (!ErrorCode && Action)
83 data << bidError; //when bid, then send 0, once...
84 SendPacket(&data);
85}
Action
Definition: boss_mandokir.cpp:72
@ SMSG_AUCTION_COMMAND_RESULT
Definition: Opcodes.h:633

References SendPacket(), and SMSG_AUCTION_COMMAND_RESULT.

Referenced by HandleAuctionPlaceBid(), HandleAuctionRemoveItem(), and HandleAuctionSellItem().

◆ SendAuctionHello()

void WorldSession::SendAuctionHello ( ObjectGuid  guid,
Creature unit 
)
54{
55 if (GetPlayer()->GetLevel() < sWorld->getIntConfig(CONFIG_AUCTION_LEVEL_REQ))
56 {
58 return;
59 }
60
61 if (!sScriptMgr->CanSendAuctionHello(this, guid, unit))
62 return;
63
65 if (!ahEntry)
66 return;
67
69 data << guid;
70 data << uint32(ahEntry->houseId);
71 data << uint8(1); // 3.3.3: 1 - AH enabled, 0 - AH disabled
72 SendPacket(&data);
73}
@ CONFIG_AUCTION_LEVEL_REQ
Definition: IWorld.h:297
@ LANG_AUCTION_REQ
Definition: Language.h:1154
@ MSG_AUCTION_HELLO
Definition: Opcodes.h:627

References CONFIG_AUCTION_LEVEL_REQ, AuctionHouseMgr::GetAuctionHouseEntry(), Unit::GetFaction(), GetPlayer(), AuctionHouseEntry::houseId, LANG_AUCTION_REQ, MSG_AUCTION_HELLO, ChatHandler::SendNotification(), SendPacket(), sScriptMgr, and sWorld.

Referenced by HandleAuctionHelloOpcode(), and Player::OnGossipSelect().

◆ SendAuctionOwnerNotification()

void WorldSession::SendAuctionOwnerNotification ( AuctionEntry auction)
103{
105 data << uint32(auction->Id);
106 data << uint32(auction->bid);
107 data << uint32(0); //unk
108 data << uint64(0); //unk (bidder guid?)
109 data << uint32(auction->item_template);
110 data << uint32(0); //unk
111 data << float(0); //unk (time?)
112 SendPacket(&data);
113}
@ SMSG_AUCTION_OWNER_NOTIFICATION
Definition: Opcodes.h:637

References AuctionEntry::bid, AuctionEntry::Id, AuctionEntry::item_template, SendPacket(), and SMSG_AUCTION_OWNER_NOTIFICATION.

Referenced by AuctionHouseMgr::SendAuctionExpiredMail(), and AuctionHouseMgr::SendAuctionSuccessfulMail().

◆ SendAuthResponse()

void WorldSession::SendAuthResponse ( uint8  code,
bool  shortForm,
uint32  queuePos = 0 
)
23{
24 WorldPacket packet(SMSG_AUTH_RESPONSE, 1 + 4 + 1 + 4 + 1 + (shortForm ? 0 : (4 + 1)));
25 packet << uint8(code);
26 packet << uint32(0); // BillingTimeRemaining
27 packet << uint8(0); // BillingPlanFlags
28 packet << uint32(0); // BillingTimeRested
29 packet << uint8(Expansion()); // 0 - normal, 1 - TBC, 2 - WOTLK, must be set in database manually for each account
30
31 if (!shortForm)
32 {
33 packet << uint32(queuePos); // Queue position
34 packet << uint8(0); // Realm has a free character migration - bool
35 }
36
37 SendPacket(&packet);
38}
@ SMSG_AUTH_RESPONSE
Definition: Opcodes.h:524

References Expansion(), SendPacket(), and SMSG_AUTH_RESPONSE.

Referenced by World::AddQueuedPlayer(), InitializeSession(), and InitializeSessionCallback().

◆ SendAuthWaitQueue()

void WorldSession::SendAuthWaitQueue ( uint32  position)

Handle the authentication waiting queue (to be completed)

828{
829 if (position == 0)
830 {
832 packet << uint8(AUTH_OK);
833 SendPacket(&packet);
834 }
835 else
836 {
838 packet << uint8(AUTH_WAIT_QUEUE);
839 packet << uint32(position);
840 packet << uint8(0); // unk
841 SendPacket(&packet);
842 }
843}
@ AUTH_WAIT_QUEUE
Definition: SharedDefines.h:3350

References AUTH_OK, AUTH_WAIT_QUEUE, SendPacket(), and SMSG_AUTH_RESPONSE.

Referenced by InitializeSessionCallback().

◆ SendBattleGroundList()

void WorldSession::SendBattleGroundList ( ObjectGuid  guid,
BattlegroundTypeId  bgTypeId = BATTLEGROUND_RB 
)
66{
67 WorldPacket data;
68 sBattlegroundMgr->BuildBattlegroundListPacket(&data, guid, _player, bgTypeId, 0);
69 SendPacket(&data);
70}

References _player, sBattlegroundMgr, and SendPacket().

Referenced by HandleBattlemasterHelloOpcode(), and Player::OnGossipSelect().

◆ SendBfEntered()

void WorldSession::SendBfEntered ( uint32  battleId)
75{
76 // m_PlayerInWar[player->GetTeamId()].insert(player->GetGUID());
78 data << uint32(BattleId);
79 data << uint8(1); //unk
80 data << uint8(1); //unk
81 data << uint8(_player->isAFK() ? 1 : 0); //Clear AFK
82 SendPacket(&data);
83}
@ SMSG_BATTLEFIELD_MGR_ENTERED
Definition: Opcodes.h:1278

References _player, Player::isAFK(), SendPacket(), and SMSG_BATTLEFIELD_MGR_ENTERED.

Referenced by Battlefield::PlayerAcceptInviteToWar().

◆ SendBfInvitePlayerToQueue()

void WorldSession::SendBfInvitePlayerToQueue ( uint32  battleId)
46{
48
49 data << uint32(BattleId);
50 data << uint8(1); //warmup ? used ?
51
52 //Sending packet to player
53 SendPacket(&data);
54}
@ SMSG_BATTLEFIELD_MGR_QUEUE_INVITE
Definition: Opcodes.h:1279

References SendPacket(), and SMSG_BATTLEFIELD_MGR_QUEUE_INVITE.

Referenced by Battlefield::InvitePlayerToQueue().

◆ SendBfInvitePlayerToWar()

void WorldSession::SendBfInvitePlayerToWar ( uint32  battleId,
uint32  zoneId,
uint32  time 
)
32{
33 //Send packet
35 data << uint32(BattleId);
36 data << uint32(ZoneId);
37 data << uint32((GameTime::GetGameTime().count() + p_time));
38
39 //Sending the packet to player
40 SendPacket(&data);
41}
@ SMSG_BATTLEFIELD_MGR_ENTRY_INVITE
Definition: Opcodes.h:1276

References GameTime::GetGameTime(), SendPacket(), and SMSG_BATTLEFIELD_MGR_ENTRY_INVITE.

Referenced by Battlefield::InvitePlayerToWar().

◆ SendBfLeaveMessage()

void WorldSession::SendBfLeaveMessage ( uint32  battleId,
BFLeaveReason  reason = BF_LEAVE_REASON_EXITED 
)
86{
88 data << uint32(BattleId);
89 data << uint8(reason);//byte Reason
90 data << uint8(2);//byte BattleStatus
91 data << uint8(0);//bool Relocated
92 SendPacket(&data);
93}
@ SMSG_BATTLEFIELD_MGR_EJECTED
Definition: Opcodes.h:1284

References SendPacket(), and SMSG_BATTLEFIELD_MGR_EJECTED.

Referenced by Battlefield::HandlePlayerLeaveZone().

◆ SendBfQueueInviteResponse()

void WorldSession::SendBfQueueInviteResponse ( uint32  battleId,
uint32  zoneId,
bool  canQueue = true,
bool  full = false 
)
62{
64 data << uint32(BattleId);
65 data << uint32(ZoneId);
66 data << uint8((CanQueue ? 1 : 0)); //Accepted //0 you cannot queue wg //1 you are queued
67 data << uint8((Full ? 0 : 1)); //Logging In //0 wg full //1 queue for upcoming
68 data << uint8(1); //Warmup
69 SendPacket(&data);
70}
@ SMSG_BATTLEFIELD_MGR_QUEUE_REQUEST_RESPONSE
Definition: Opcodes.h:1282

References SendPacket(), and SMSG_BATTLEFIELD_MGR_QUEUE_REQUEST_RESPONSE.

Referenced by Battlefield::PlayerAcceptInviteToQueue().

◆ SendBindPoint()

void WorldSession::SendBindPoint ( Creature npc)
441{
442 // prevent set homebind to instances in any case
443 if (GetPlayer()->GetMap()->Instanceable())
444 return;
445
446 uint32 bindspell = 3286;
447
448 // send spell for homebinding (3286)
449 npc->CastSpell(_player, bindspell, true);
450
452 data << npc->GetGUID();
453 data << uint32(bindspell);
454 SendPacket(&data);
455
457}

References _player, GetPlayer(), Player::PlayerTalkClass, PlayerMenu::SendCloseGossip(), SendPacket(), and SMSG_TRAINER_BUY_SUCCEEDED.

Referenced by HandleBinderActivateOpcode().

◆ SendCalendarRaidLockout()

void WorldSession::SendCalendarRaidLockout ( InstanceSave const *  save,
bool  add 
)
819{
820 LOG_DEBUG("network", "{}", add ? "SMSG_CALENDAR_RAID_LOCKOUT_ADDED" : "SMSG_CALENDAR_RAID_LOCKOUT_REMOVED");
821 time_t currTime = GameTime::GetGameTime().count();
822
823 WorldPacket data(SMSG_CALENDAR_RAID_LOCKOUT_REMOVED, (add ? 4 : 0) + 4 + 4 + 4 + 8);
824 if (add)
825 {
826 data.SetOpcode(SMSG_CALENDAR_RAID_LOCKOUT_ADDED);
827 data.AppendPackedTime(currTime);
828 }
829
830 data << uint32(save->GetMapId());
831 data << uint32(save->GetDifficulty());
832 data << uint32(save->GetResetTime() >= currTime ? save->GetResetTime() - currTime : 0);
833 data << ObjectGuid::Create<HighGuid::Instance>(save->GetInstanceId());
834 SendPacket(&data);
835}
@ SMSG_CALENDAR_RAID_LOCKOUT_ADDED
Definition: Opcodes.h:1116
@ SMSG_CALENDAR_RAID_LOCKOUT_REMOVED
Definition: Opcodes.h:1117

References ByteBuffer::AppendPackedTime(), InstanceSave::GetDifficulty(), GameTime::GetGameTime(), InstanceSave::GetInstanceId(), InstanceSave::GetMapId(), InstanceSave::GetResetTime(), LOG_DEBUG, SendPacket(), WorldPacket::SetOpcode(), SMSG_CALENDAR_RAID_LOCKOUT_ADDED, and SMSG_CALENDAR_RAID_LOCKOUT_REMOVED.

Referenced by InstanceSaveMgr::PlayerBindToInstance(), InstanceSaveMgr::PlayerUnbindInstance(), and InstanceSaveMgr::PlayerUnbindInstanceNotExtended().

◆ SendCalendarRaidLockoutUpdated()

void WorldSession::SendCalendarRaidLockoutUpdated ( InstanceSave const *  save,
bool  isExtended 
)
838{
839 time_t currTime = GameTime::GetGameTime().count();
840 time_t resetTime = isExtended ? save->GetExtendedResetTime() : save->GetResetTime();
841 time_t resetTimeOp = isExtended ? save->GetResetTime() : save->GetExtendedResetTime();
842 WorldPacket data(SMSG_CALENDAR_RAID_LOCKOUT_UPDATED, 4 + 4 + 4 + 4 + 8);
843 data.AppendPackedTime(currTime);
844 data << uint32(save->GetMapId());
845 data << uint32(save->GetDifficulty());
846 data << uint32(resetTimeOp >= currTime ? resetTimeOp - currTime : resetTimeOp); // pussywizard: old time in secs to reset
847 data << uint32(resetTime >= currTime ? resetTime - currTime : 0); // pussywizard: new time in secs to reset
848 SendPacket(&data);
849}
@ SMSG_CALENDAR_RAID_LOCKOUT_UPDATED
Definition: Opcodes.h:1167

References ByteBuffer::AppendPackedTime(), InstanceSave::GetDifficulty(), InstanceSave::GetExtendedResetTime(), GameTime::GetGameTime(), InstanceSave::GetMapId(), InstanceSave::GetResetTime(), SendPacket(), and SMSG_CALENDAR_RAID_LOCKOUT_UPDATED.

Referenced by HandleSetSavedInstanceExtend().

◆ SendCancelTrade()

void WorldSession::SendCancelTrade ( )
530{
532 return;
533
535}
bool PlayerRecentlyLoggedOut() const
Definition: WorldSession.h:339

References PlayerLogout(), PlayerRecentlyLoggedOut(), SendTradeStatus(), and TRADE_STATUS_TRADE_CANCELED.

Referenced by Player::TradeCancel(), and Player::UpdatePosition().

◆ SendCharCreate()

void WorldSession::SendCharCreate ( ResponseCodes  result)
2560{
2562 data << uint8(result);
2563 SendPacket(&data);
2564}
@ SMSG_CHAR_CREATE
Definition: Opcodes.h:88

References SendPacket(), and SMSG_CHAR_CREATE.

Referenced by HandleCharCreateOpcode().

◆ SendCharCustomize()

void WorldSession::SendCharCustomize ( ResponseCodes  result,
CharacterCustomizeInfo const *  customizeInfo 
)
2605{
2606 WorldPacket data(SMSG_CHAR_CUSTOMIZE, 1 + 8 + customizeInfo->Name.size() + 1 + 6);
2607 data << uint8(result);
2608 if (result == RESPONSE_SUCCESS)
2609 {
2610 data << customizeInfo->Guid;
2611 data << customizeInfo->Name;
2612 data << uint8(customizeInfo->Gender);
2613 data << uint8(customizeInfo->Skin);
2614 data << uint8(customizeInfo->Face);
2615 data << uint8(customizeInfo->HairStyle);
2616 data << uint8(customizeInfo->HairColor);
2617 data << uint8(customizeInfo->FacialHair);
2618 }
2619 SendPacket(&data);
2620}

References CharacterCustomizeInfo::Face, CharacterCustomizeInfo::FacialHair, CharacterCustomizeInfo::Gender, CharacterRenameInfo::Guid, CharacterCustomizeInfo::HairColor, CharacterCustomizeInfo::HairStyle, CharacterRenameInfo::Name, RESPONSE_SUCCESS, SendPacket(), CharacterCustomizeInfo::Skin, and SMSG_CHAR_CUSTOMIZE.

Referenced by HandleCharCustomizeCallback().

◆ SendCharDelete()

void WorldSession::SendCharDelete ( ResponseCodes  result)
2567{
2569 data << uint8(result);
2570 SendPacket(&data);
2571}
@ SMSG_CHAR_DELETE
Definition: Opcodes.h:90

References SendPacket(), and SMSG_CHAR_DELETE.

Referenced by HandleCharDeleteOpcode().

◆ SendCharFactionChange()

void WorldSession::SendCharFactionChange ( ResponseCodes  result,
CharacterFactionChangeInfo const *  factionChangeInfo 
)
2586{
2587 WorldPacket data(SMSG_CHAR_FACTION_CHANGE, 1 + 8 + factionChangeInfo->Name.size() + 1 + 7);
2588 data << uint8(result);
2589 if (result == RESPONSE_SUCCESS)
2590 {
2591 data << factionChangeInfo->Guid;
2592 data << factionChangeInfo->Name;
2593 data << uint8(factionChangeInfo->Gender);
2594 data << uint8(factionChangeInfo->Skin);
2595 data << uint8(factionChangeInfo->Face);
2596 data << uint8(factionChangeInfo->HairStyle);
2597 data << uint8(factionChangeInfo->HairColor);
2598 data << uint8(factionChangeInfo->FacialHair);
2599 data << uint8(factionChangeInfo->Race);
2600 }
2601 SendPacket(&data);
2602}
@ SMSG_CHAR_FACTION_CHANGE
Definition: Opcodes.h:1272

References CharacterCustomizeInfo::Face, CharacterCustomizeInfo::FacialHair, CharacterCustomizeInfo::Gender, CharacterRenameInfo::Guid, CharacterCustomizeInfo::HairColor, CharacterCustomizeInfo::HairStyle, CharacterRenameInfo::Name, CharacterFactionChangeInfo::Race, RESPONSE_SUCCESS, SendPacket(), CharacterCustomizeInfo::Skin, and SMSG_CHAR_FACTION_CHANGE.

Referenced by HandleCharFactionOrRaceChange(), and HandleCharFactionOrRaceChangeCallback().

◆ SendCharRename()

void WorldSession::SendCharRename ( ResponseCodes  result,
CharacterRenameInfo const *  renameInfo 
)
2574{
2575 WorldPacket data(SMSG_CHAR_RENAME, 1 + 8 + renameInfo->Name.size() + 1);
2576 data << uint8(result);
2577 if (result == RESPONSE_SUCCESS)
2578 {
2579 data << renameInfo->Guid;
2580 data << renameInfo->Name;
2581 }
2582 SendPacket(&data);
2583}
@ SMSG_CHAR_RENAME
Definition: Opcodes.h:742

References CharacterRenameInfo::Guid, CharacterRenameInfo::Name, RESPONSE_SUCCESS, SendPacket(), and SMSG_CHAR_RENAME.

Referenced by HandleCharRenameCallBack(), and HandleCharRenameOpcode().

◆ SendChatRestrictedNotice()

void WorldSession::SendChatRestrictedNotice ( ChatRestrictionType  restriction)
844{
846 data << uint8(restriction);
847 SendPacket(&data);
848}
@ SMSG_CHAT_RESTRICTED
Definition: Opcodes.h:795

References SendPacket(), and SMSG_CHAT_RESTRICTED.

◆ SendClientCacheVersion()

void WorldSession::SendClientCacheVersion ( uint32  version)
41{
43 data << uint32(version);
44 SendPacket(&data);
45}
@ SMSG_CLIENTCACHE_VERSION
Definition: Opcodes.h:1225

References SendPacket(), and SMSG_CLIENTCACHE_VERSION.

Referenced by InitializeSessionCallback().

◆ SendDiscoverNewTaxiNode()

void WorldSession::SendDiscoverNewTaxiNode ( uint32  nodeid)
152{
153 if (GetPlayer()->m_taxi.SetTaximaskNode(nodeid))
154 {
156 SendPacket(&msg);
157 }
158}
@ SMSG_NEW_TAXI_PATH
Definition: Opcodes.h:461

References GetPlayer(), SendPacket(), and SMSG_NEW_TAXI_PATH.

Referenced by Spell::EffectDiscoverTaxi().

◆ SendDoFlight()

void WorldSession::SendDoFlight ( uint32  mountDisplayId,
uint32  path,
uint32  pathNode = 0 
)
110{
111 // remove fake death
112 if (GetPlayer()->HasUnitState(UNIT_STATE_DIED))
114
115 while (GetPlayer()->GetMotionMaster()->GetCurrentMovementGeneratorType() == FLIGHT_MOTION_TYPE)
117
118 if (mountDisplayId)
119 GetPlayer()->Mount(mountDisplayId);
120
121 if (Creature* critter = ObjectAccessor::GetCreature(*GetPlayer(), GetPlayer()->GetCritterGUID()))
122 critter->DespawnOrUnsummon();
123
124 GetPlayer()->GetMotionMaster()->MoveTaxiFlight(path, pathNode);
125}
Creature * GetCreature(WorldObject const &u, ObjectGuid const guid)
Definition: ObjectAccessor.cpp:210
void Mount(uint32 mount, uint32 vehicleId=0, uint32 creatureEntry=0)
Definition: Unit.cpp:13429
void MoveTaxiFlight(uint32 path, uint32 pathnode)
Definition: MotionMaster.cpp:771

References FLIGHT_MOTION_TYPE, ObjectAccessor::GetCreature(), Unit::GetMotionMaster(), GetPlayer(), Unit::Mount(), MotionMaster::MovementExpired(), MotionMaster::MoveTaxiFlight(), Unit::RemoveAurasByType(), SPELL_AURA_FEIGN_DEATH, and UNIT_STATE_DIED.

Referenced by Player::ActivateTaxiPathTo(), and Player::ContinueTaxiFlight().

◆ SendEnchantmentLog()

void WorldSession::SendEnchantmentLog ( ObjectGuid  target,
ObjectGuid  caster,
uint32  itemId,
uint32  enchantId 
)
1224{
1225 WorldPacket data(SMSG_ENCHANTMENTLOG, (8 + 8 + 4 + 4)); // last check 2.0.10
1226 data << target.WriteAsPacked();
1227 data << caster.WriteAsPacked();
1228 data << uint32(itemId);
1229 data << uint32(enchantId);
1230 GetPlayer()->SendMessageToSet(&data, true);
1231}
@ SMSG_ENCHANTMENTLOG
Definition: Opcodes.h:501

References GetPlayer(), Player::SendMessageToSet(), SMSG_ENCHANTMENTLOG, and ObjectGuid::WriteAsPacked().

Referenced by Item::SetEnchantment().

◆ SendItemEnchantTimeUpdate()

void WorldSession::SendItemEnchantTimeUpdate ( ObjectGuid  Playerguid,
ObjectGuid  Itemguid,
uint32  slot,
uint32  Duration 
)
1234{
1235 // last check 2.0.10
1236 WorldPacket data(SMSG_ITEM_ENCHANT_TIME_UPDATE, (8 + 4 + 4 + 8));
1237 data << Itemguid;
1238 data << uint32(slot);
1239 data << uint32(Duration);
1240 data << Playerguid;
1241 SendPacket(&data);
1242}
@ SMSG_ITEM_ENCHANT_TIME_UPDATE
Definition: Opcodes.h:521

References SendPacket(), and SMSG_ITEM_ENCHANT_TIME_UPDATE.

Referenced by Player::AddEnchantmentDuration(), and Player::SendEnchantmentDurations().

◆ SendLearnNewTaxiNode()

bool WorldSession::SendLearnNewTaxiNode ( Creature unit)
128{
129 // find current node
130 uint32 curloc = sObjectMgr->GetNearestTaxiNode(unit->GetPositionX(), unit->GetPositionY(), unit->GetPositionZ(), unit->GetMapId(), GetPlayer()->GetTeamId());
131
132 if (curloc == 0)
133 return true; // `true` send to avoid WorldSession::SendTaxiMenu call with one more curlock seartch with same false result.
134
135 if (GetPlayer()->m_taxi.SetTaximaskNode(curloc))
136 {
138 SendPacket(&msg);
139
141 update << unit->GetGUID();
142 update << uint8(1);
143 SendPacket(&update);
144
145 return true;
146 }
147 else
148 return false;
149}
@ SMSG_TAXINODE_STATUS
Definition: Opcodes.h:457

References Object::GetGUID(), WorldLocation::GetMapId(), GetPlayer(), Position::GetPositionX(), Position::GetPositionY(), Position::GetPositionZ(), GetTeamId(), SendPacket(), SMSG_NEW_TAXI_PATH, SMSG_TAXINODE_STATUS, and sObjectMgr.

Referenced by HandleTaxiQueryAvailableNodes().

◆ SendLfgBootProposalUpdate()

void WorldSession::SendLfgBootProposalUpdate ( lfg::LfgPlayerBoot const &  boot)
506{
507 ObjectGuid guid = GetPlayer()->GetGUID();
508 lfg::LfgAnswer playerVote = boot.votes.find(guid)->second;
509 uint8 votesNum = 0;
510 uint8 agreeNum = 0;
511 uint32 secsleft = boot.cancelTime - GameTime::GetGameTime().count();
512 for (lfg::LfgAnswerContainer::const_iterator it = boot.votes.begin(); it != boot.votes.end(); ++it)
513 {
514 if (it->second != lfg::LFG_ANSWER_PENDING)
515 {
516 ++votesNum;
517 if (it->second == lfg::LFG_ANSWER_AGREE)
518 ++agreeNum;
519 }
520 }
521 LOG_DEBUG("network", "SMSG_LFG_BOOT_PROPOSAL_UPDATE [{}] inProgress: {} - didVote: {} - agree: {} - victim: [{}] votes: {} - agrees: {} - left: {} - needed: {} - reason {}",
522 guid.ToString(), uint8(boot.inProgress), uint8(playerVote != lfg::LFG_ANSWER_PENDING), uint8(playerVote == lfg::LFG_ANSWER_AGREE),
523 boot.victim.ToString(), votesNum, agreeNum, secsleft, lfg::LFG_GROUP_KICK_VOTES_NEEDED, boot.reason);
524 WorldPacket data(SMSG_LFG_BOOT_PROPOSAL_UPDATE, 1 + 1 + 1 + 8 + 4 + 4 + 4 + 4 + boot.reason.length());
525 data << uint8(boot.inProgress); // Vote in progress
526 data << uint8(playerVote != lfg::LFG_ANSWER_PENDING); // Did Vote
527 data << uint8(playerVote == lfg::LFG_ANSWER_AGREE); // Agree
528 data << boot.victim; // Victim GUID
529 data << uint32(votesNum); // Total Votes
530 data << uint32(agreeNum); // Agree Count
531 data << uint32(secsleft); // Time Left
532 data << uint32(lfg::LFG_GROUP_KICK_VOTES_NEEDED); // Needed Votes
533 data << boot.reason.c_str(); // Kick reason
534 SendPacket(&data);
535}
@ SMSG_LFG_BOOT_PROPOSAL_UPDATE
Definition: Opcodes.h:907
@ LFG_GROUP_KICK_VOTES_NEEDED
Definition: LFGMgr.h:55
LfgAnswer
Answer state (Also used to check compatibilites)
Definition: LFG.h:100
@ LFG_ANSWER_AGREE
Definition: LFG.h:103
@ LFG_ANSWER_PENDING
Definition: LFG.h:101

References lfg::LfgPlayerBoot::cancelTime, GameTime::GetGameTime(), Object::GetGUID(), GetPlayer(), lfg::LfgPlayerBoot::inProgress, lfg::LFG_ANSWER_AGREE, lfg::LFG_ANSWER_PENDING, lfg::LFG_GROUP_KICK_VOTES_NEEDED, LOG_DEBUG, lfg::LfgPlayerBoot::reason, SendPacket(), SMSG_LFG_BOOT_PROPOSAL_UPDATE, ObjectGuid::ToString(), lfg::LfgPlayerBoot::victim, and lfg::LfgPlayerBoot::votes.

◆ SendLfgDisabled()

void WorldSession::SendLfgDisabled ( )
594{
595 LOG_DEBUG("network", "SMSG_LFG_DISABLED [{}]", GetPlayer()->GetGUID().ToString());
597 SendPacket(&data);
598}
@ SMSG_LFG_DISABLED
Definition: Opcodes.h:950

References GetPlayer(), LOG_DEBUG, SendPacket(), and SMSG_LFG_DISABLED.

◆ SendLfgJoinResult()

void WorldSession::SendLfgJoinResult ( lfg::LfgJoinResultData const &  joinData)
436{
437 uint32 size = 0;
438 for (lfg::LfgLockPartyMap::const_iterator it = joinData.lockmap.begin(); it != joinData.lockmap.end(); ++it)
439 size += 8 + 4 + uint32(it->second.size()) * (4 + 4);
440
441 LOG_DEBUG("network", "SMSG_LFG_JOIN_RESULT [{}] checkResult: {} checkValue: {}", GetPlayer()->GetGUID().ToString(), joinData.result, joinData.state);
442 WorldPacket data(SMSG_LFG_JOIN_RESULT, 4 + 4 + size);
443 data << uint32(joinData.result); // Check Result
444 data << uint32(joinData.state); // Check Value
445 if (!joinData.lockmap.empty())
446 BuildPartyLockDungeonBlock(data, joinData.lockmap);
447 SendPacket(&data);
448}
@ SMSG_LFG_JOIN_RESULT
Definition: Opcodes.h:898

References BuildPartyLockDungeonBlock(), GetPlayer(), lfg::LfgJoinResultData::lockmap, LOG_DEBUG, lfg::LfgJoinResultData::result, SendPacket(), SMSG_LFG_JOIN_RESULT, and lfg::LfgJoinResultData::state.

Referenced by lfg::LFGMgr::JoinLfg(), and lfg::LFGMgr::SendRaidBrowserJoinedPacket().

◆ SendLfgLfrList()

void WorldSession::SendLfgLfrList ( bool  update)
586{
587 LOG_DEBUG("network", "SMSG_LFG_LFR_LIST [{}] update: {}", GetPlayer()->GetGUID().ToString(), update ? 1 : 0);
589 data << uint8(update); // In Lfg Queue?
590 SendPacket(&data);
591}
@ SMSG_LFG_UPDATE_SEARCH
Definition: Opcodes.h:903

References GetPlayer(), LOG_DEBUG, SendPacket(), and SMSG_LFG_UPDATE_SEARCH.

Referenced by lfg::LFGPlayerScript::OnLogout().

◆ SendLfgOfferContinue()

void WorldSession::SendLfgOfferContinue ( uint32  dungeonEntry)
601{
602 LOG_DEBUG("network", "SMSG_LFG_OFFER_CONTINUE [{}] dungeon entry: {}", GetPlayer()->GetGUID().ToString(), dungeonEntry);
604 data << uint32(dungeonEntry);
605 SendPacket(&data);
606}
@ SMSG_LFG_OFFER_CONTINUE
Definition: Opcodes.h:689

References GetPlayer(), LOG_DEBUG, SendPacket(), and SMSG_LFG_OFFER_CONTINUE.

◆ SendLfgPlayerReward()

void WorldSession::SendLfgPlayerReward ( lfg::LfgPlayerRewardData const &  lfgPlayerRewardData)
470{
471 if (!rewardData.rdungeonEntry || !rewardData.sdungeonEntry || !rewardData.quest)
472 return;
473
474 LOG_DEBUG("lfg", "SMSG_LFG_PLAYER_REWARD {} rdungeonEntry: {}, sdungeonEntry: {}, done: {}",
475 GetPlayerInfo(), rewardData.rdungeonEntry, rewardData.sdungeonEntry, rewardData.done);
476
477 uint8 itemNum = rewardData.quest->GetRewItemsCount();
478
479 uint8 playerLevel = GetPlayer() ? GetPlayer()->GetLevel() : 0;
480
481 WorldPacket data(SMSG_LFG_PLAYER_REWARD, 4 + 4 + 1 + 4 + 4 + 4 + 4 + 4 + 1 + itemNum * (4 + 4 + 4));
482 data << uint32(rewardData.rdungeonEntry); // Random Dungeon Finished
483 data << uint32(rewardData.sdungeonEntry); // Dungeon Finished
484 data << uint8(rewardData.done);
485 data << uint32(1);
486 data << uint32(rewardData.quest->GetRewOrReqMoney(playerLevel));
487 data << uint32(rewardData.quest->XPValue(playerLevel));
488 data << uint32(0);
489 data << uint32(0);
490 data << uint8(itemNum);
491 if (itemNum)
492 {
493 for (uint8 i = 0; i < QUEST_REWARDS_COUNT; ++i)
494 if (uint32 itemId = rewardData.quest->RewardItemId[i])
495 {
496 ItemTemplate const* item = sObjectMgr->GetItemTemplate(itemId);
497 data << uint32(itemId);
498 data << uint32(item ? item->DisplayInfoID : 0);
499 data << uint32(rewardData.quest->RewardItemIdCount[i]);
500 }
501 }
502 SendPacket(&data);
503}
@ SMSG_LFG_PLAYER_REWARD
Definition: Opcodes.h:541

References ItemTemplate::DisplayInfoID, lfg::LfgPlayerRewardData::done, Unit::GetLevel(), GetPlayer(), GetPlayerInfo(), Quest::GetRewItemsCount(), Quest::GetRewOrReqMoney(), LOG_DEBUG, lfg::LfgPlayerRewardData::quest, QUEST_REWARDS_COUNT, lfg::LfgPlayerRewardData::rdungeonEntry, Quest::RewardItemId, Quest::RewardItemIdCount, lfg::LfgPlayerRewardData::sdungeonEntry, SendPacket(), SMSG_LFG_PLAYER_REWARD, sObjectMgr, and Quest::XPValue().

Referenced by lfg::LFGMgr::FinishDungeon().

◆ SendLfgQueueStatus()

void WorldSession::SendLfgQueueStatus ( lfg::LfgQueueStatusData const &  queueData)
451{
452 LOG_DEBUG("network", "SMSG_LFG_QUEUE_STATUS [{}] dungeon: {} - waitTime: {} - avgWaitTime: {} - waitTimeTanks: {} - waitTimeHealer: {} - waitTimeDps: {} - queuedTime: {} - tanks: {} - healers: {} - dps: {}",
453 GetPlayer()->GetGUID().ToString(), queueData.dungeonId, queueData.waitTime, queueData.waitTimeAvg, queueData.waitTimeTank,
454 queueData.waitTimeHealer, queueData.waitTimeDps, queueData.queuedTime, queueData.tanks, queueData.healers, queueData.dps);
455 WorldPacket data(SMSG_LFG_QUEUE_STATUS, 4 + 4 + 4 + 4 + 4 + 4 + 1 + 1 + 1 + 4);
456 data << uint32(queueData.dungeonId); // Dungeon
457 data << int32(queueData.waitTimeAvg); // Average Wait time
458 data << int32(queueData.waitTime); // Wait Time
459 data << int32(queueData.waitTimeTank); // Wait Tanks
460 data << int32(queueData.waitTimeHealer); // Wait Healers
461 data << int32(queueData.waitTimeDps); // Wait Dps
462 data << uint8(queueData.tanks); // Tanks needed
463 data << uint8(queueData.healers); // Healers needed
464 data << uint8(queueData.dps); // Dps needed
465 data << uint32(queueData.queuedTime); // Player wait time in queue
466 SendPacket(&data);
467}
@ SMSG_LFG_QUEUE_STATUS
Definition: Opcodes.h:899

References lfg::LfgQueueStatusData::dps, lfg::LfgQueueStatusData::dungeonId, GetPlayer(), lfg::LfgQueueStatusData::healers, LOG_DEBUG, lfg::LfgQueueStatusData::queuedTime, SendPacket(), SMSG_LFG_QUEUE_STATUS, lfg::LfgQueueStatusData::tanks, lfg::LfgQueueStatusData::waitTime, lfg::LfgQueueStatusData::waitTimeAvg, lfg::LfgQueueStatusData::waitTimeDps, lfg::LfgQueueStatusData::waitTimeHealer, and lfg::LfgQueueStatusData::waitTimeTank.

◆ SendLfgRoleCheckUpdate()

void WorldSession::SendLfgRoleCheckUpdate ( lfg::LfgRoleCheck const &  pRoleCheck)
389{
390 lfg::LfgDungeonSet dungeons;
391 if (roleCheck.rDungeonId)
392 dungeons.insert(roleCheck.rDungeonId);
393 else
394 dungeons = roleCheck.dungeons;
395
396 LOG_DEBUG("network", "SMSG_LFG_ROLE_CHECK_UPDATE [{}]", GetPlayer()->GetGUID().ToString());
397 WorldPacket data(SMSG_LFG_ROLE_CHECK_UPDATE, 4 + 1 + 1 + dungeons.size() * 4 + 1 + roleCheck.roles.size() * (8 + 1 + 4 + 1));
398
399 data << uint32(roleCheck.state); // Check result
400 data << uint8(roleCheck.state == lfg::LFG_ROLECHECK_INITIALITING);
401 data << uint8(dungeons.size()); // Number of dungeons
402 if (!dungeons.empty())
403 for (lfg::LfgDungeonSet::iterator it = dungeons.begin(); it != dungeons.end(); ++it)
404 data << uint32(sLFGMgr->GetLFGDungeonEntry(*it)); // Dungeon
405
406 data << uint8(roleCheck.roles.size()); // Players in group
407 if (!roleCheck.roles.empty())
408 {
409 // Leader info MUST be sent 1st :S
410 ObjectGuid guid = roleCheck.leader;
411 uint8 roles = roleCheck.roles.find(guid)->second;
412 data << guid; // Guid
413 data << uint8(roles > 0); // Ready
414 data << uint32(roles); // Roles
416 data << uint8(player ? player->GetLevel() : 0); // Level
417
418 for (lfg::LfgRolesMap::const_iterator it = roleCheck.roles.begin(); it != roleCheck.roles.end(); ++it)
419 {
420 if (it->first == roleCheck.leader)
421 continue;
422
423 guid = it->first;
424 roles = it->second;
425 data << guid; // Guid
426 data << uint8(roles > 0); // Ready
427 data << uint32(roles); // Roles
429 data << uint8(player ? player->GetLevel() : 0);// Level
430 }
431 }
432 SendPacket(&data);
433}
@ SMSG_LFG_ROLE_CHECK_UPDATE
Definition: Opcodes.h:897
@ LFG_ROLECHECK_INITIALITING
Definition: LFGMgr.h:126

References lfg::LfgRoleCheck::dungeons, ObjectAccessor::FindConnectedPlayer(), Unit::GetLevel(), GetPlayer(), lfg::LfgRoleCheck::leader, lfg::LFG_ROLECHECK_INITIALITING, LOG_DEBUG, lfg::LfgRoleCheck::rDungeonId, lfg::LfgRoleCheck::roles, SendPacket(), sLFGMgr, SMSG_LFG_ROLE_CHECK_UPDATE, and lfg::LfgRoleCheck::state.

◆ SendLfgRoleChosen()

void WorldSession::SendLfgRoleChosen ( ObjectGuid  guid,
uint8  roles 
)
378{
379 LOG_DEBUG("network", "SMSG_LFG_ROLE_CHOSEN [{}] guid: [{}] roles: {}", GetPlayer()->GetGUID().ToString(), guid.ToString(), roles);
380
381 WorldPacket data(SMSG_LFG_ROLE_CHOSEN, 8 + 1 + 4);
382 data << guid; // Guid
383 data << uint8(roles > 0); // Ready
384 data << uint32(roles); // Roles
385 SendPacket(&data);
386}
@ SMSG_LFG_ROLE_CHOSEN
Definition: Opcodes.h:729

References GetPlayer(), LOG_DEBUG, SendPacket(), SMSG_LFG_ROLE_CHOSEN, and ObjectGuid::ToString().

◆ SendLfgTeleportError()

void WorldSession::SendLfgTeleportError ( uint8  err)
609{
610 LOG_DEBUG("network", "SMSG_LFG_TELEPORT_DENIED [{}] reason: {}", GetPlayer()->GetGUID().ToString(), err);
612 data << uint32(err); // Error
613 SendPacket(&data);
614}
@ SMSG_LFG_TELEPORT_DENIED
Definition: Opcodes.h:542

References GetPlayer(), LOG_DEBUG, SendPacket(), and SMSG_LFG_TELEPORT_DENIED.

Referenced by lfg::LFGMgr::TeleportPlayer().

◆ SendLfgUpdateParty()

void WorldSession::SendLfgUpdateParty ( lfg::LfgUpdateData const &  updateData)
334{
335 bool join = false;
336 bool queued = false;
337 uint8 size = uint8(updateData.dungeons.size());
338
339 switch (updateData.updateType)
340 {
341 case lfg::LFG_UPDATETYPE_ADDED_TO_QUEUE: // Rolecheck Success
342 queued = true;
343 [[fallthrough]];
345 join = true;
346 break;
348 join = updateData.state != lfg::LFG_STATE_ROLECHECK && updateData.state != lfg::LFG_STATE_NONE;
349 queued = updateData.state == lfg::LFG_STATE_QUEUED;
350 break;
351 default:
352 break;
353 }
354
355 LOG_DEBUG("lfg", "SMSG_LFG_UPDATE_PARTY {} updatetype: {}",
356 GetPlayerInfo(), updateData.updateType);
357 WorldPacket data(SMSG_LFG_UPDATE_PARTY, 1 + 1 + (size > 0 ? 1 : 0) * (1 + 1 + 1 + 1 + 1 + size * 4 + updateData.comment.length()));
358 data << uint8(updateData.updateType); // Lfg Update type
359 data << uint8(size > 0); // Extra info
360 if (size)
361 {
362 data << uint8(join); // LFG Join
363 data << uint8(queued); // Join the queue
364 data << uint8(0); // unk - Always 0
365 data << uint8(0); // unk - Always 0
366 for (uint8 i = 0; i < 3; ++i)
367 data << uint8(0); // unk - Always 0
368
369 data << uint8(size);
370 for (lfg::LfgDungeonSet::const_iterator it = updateData.dungeons.begin(); it != updateData.dungeons.end(); ++it)
371 data << uint32(*it);
372 data << updateData.comment;
373 }
374 SendPacket(&data);
375}
@ SMSG_LFG_UPDATE_PARTY
Definition: Opcodes.h:902
@ LFG_STATE_ROLECHECK
Definition: LFG.h:72
@ LFG_UPDATETYPE_ADDED_TO_QUEUE
Definition: LFG.h:62
@ LFG_UPDATETYPE_UPDATE_STATUS
Definition: LFG.h:64
@ LFG_UPDATETYPE_PROPOSAL_BEGIN
Definition: LFG.h:63

References lfg::LfgUpdateData::comment, lfg::LfgUpdateData::dungeons, GetPlayerInfo(), lfg::LFG_STATE_NONE, lfg::LFG_STATE_QUEUED, lfg::LFG_STATE_ROLECHECK, lfg::LFG_UPDATETYPE_ADDED_TO_QUEUE, lfg::LFG_UPDATETYPE_PROPOSAL_BEGIN, lfg::LFG_UPDATETYPE_UPDATE_STATUS, LOG_DEBUG, SendPacket(), SMSG_LFG_UPDATE_PARTY, lfg::LfgUpdateData::state, and lfg::LfgUpdateData::updateType.

Referenced by HandleLfgGetStatus(), and lfg::LFGMgr::SendRaidBrowserJoinedPacket().

◆ SendLfgUpdatePlayer()

void WorldSession::SendLfgUpdatePlayer ( lfg::LfgUpdateData const &  updateData)
297{
298 bool queued = false;
299 uint8 size = uint8(updateData.dungeons.size());
300
301 switch (updateData.updateType)
302 {
305 queued = true;
306 break;
308 queued = updateData.state == lfg::LFG_STATE_QUEUED;
309 break;
310 default:
311 break;
312 }
313
314 LOG_DEBUG("lfg", "SMSG_LFG_UPDATE_PLAYER {} updatetype: {}",
315 GetPlayerInfo(), updateData.updateType);
316 WorldPacket data(SMSG_LFG_UPDATE_PLAYER, 1 + 1 + (size > 0 ? 1 : 0) * (1 + 1 + 1 + 1 + size * 4 + updateData.comment.length()));
317 data << uint8(updateData.updateType); // Lfg Update type
318 data << uint8(size > 0); // Extra info
319 if (size)
320 {
321 data << uint8(queued); // Join the queue
322 data << uint8(0); // unk - Always 0
323 data << uint8(0); // unk - Always 0
324
325 data << uint8(size);
326 for (lfg::LfgDungeonSet::const_iterator it = updateData.dungeons.begin(); it != updateData.dungeons.end(); ++it)
327 data << uint32(*it);
328 data << updateData.comment;
329 }
330 SendPacket(&data);
331}
@ SMSG_LFG_UPDATE_PLAYER
Definition: Opcodes.h:901
@ LFG_UPDATETYPE_JOIN_QUEUE
Definition: LFG.h:56

References lfg::LfgUpdateData::comment, lfg::LfgUpdateData::dungeons, GetPlayerInfo(), lfg::LFG_STATE_QUEUED, lfg::LFG_UPDATETYPE_ADDED_TO_QUEUE, lfg::LFG_UPDATETYPE_JOIN_QUEUE, lfg::LFG_UPDATETYPE_UPDATE_STATUS, LOG_DEBUG, SendPacket(), SMSG_LFG_UPDATE_PLAYER, lfg::LfgUpdateData::state, and lfg::LfgUpdateData::updateType.

Referenced by HandleLfgGetStatus(), lfg::LFGMgr::JoinLfg(), and lfg::LFGMgr::SendRaidBrowserJoinedPacket().

◆ SendLfgUpdateProposal()

void WorldSession::SendLfgUpdateProposal ( lfg::LfgProposal const &  proposal)
538{
539 ObjectGuid guid = GetPlayer()->GetGUID();
540 ObjectGuid gguid = proposal.players.find(guid)->second.group;
541 bool silent = !proposal.isNew && gguid == proposal.group;
542 uint32 dungeonEntry = proposal.dungeonId;
543
544 LOG_DEBUG("network", "SMSG_LFG_PROPOSAL_UPDATE [{} state: {}", guid.ToString(), proposal.state);
545
546 // show random dungeon if player selected random dungeon and it's not lfg group
547 if (!silent)
548 {
549 lfg::LfgDungeonSet const& playerDungeons = sLFGMgr->GetSelectedDungeons(guid);
550 if (playerDungeons.find(proposal.dungeonId) == playerDungeons.end())
551 dungeonEntry = (*playerDungeons.begin());
552 }
553
554 dungeonEntry = sLFGMgr->GetLFGDungeonEntry(dungeonEntry);
555
556 WorldPacket data(SMSG_LFG_PROPOSAL_UPDATE, 4 + 1 + 4 + 4 + 1 + 1 + proposal.players.size() * (4 + 1 + 1 + 1 + 1 + 1));
557 data << uint32(dungeonEntry); // Dungeon
558 data << uint8(proposal.state); // Proposal state
559 data << uint32(proposal.id); // Proposal ID
560 data << uint32(proposal.encounters); // encounters done
561 data << uint8(silent); // Show proposal window
562 data << uint8(proposal.players.size()); // Group size
563
564 for (lfg::LfgProposalPlayerContainer::const_iterator it = proposal.players.begin(); it != proposal.players.end(); ++it)
565 {
566 lfg::LfgProposalPlayer const& player = it->second;
567 data << uint32(player.role); // Role
568 data << uint8(it->first == guid); // Self player
569 if (!player.group) // Player not it a group
570 {
571 data << uint8(0); // Not in dungeon
572 data << uint8(0); // Not same group
573 }
574 else
575 {
576 data << uint8(player.group == proposal.group); // In dungeon (silent)
577 data << uint8(player.group == gguid); // Same Group than player
578 }
579 data << uint8(player.accept != lfg::LFG_ANSWER_PENDING);// Answered
580 data << uint8(player.accept == lfg::LFG_ANSWER_AGREE); // Accepted
581 }
582 SendPacket(&data);
583}
@ SMSG_LFG_PROPOSAL_UPDATE
Definition: Opcodes.h:895
Definition: LFGMgr.h:346
uint8 role
Proposed role.
Definition: LFGMgr.h:348
ObjectGuid group
Original group guid. 0 if no original group.
Definition: LFGMgr.h:350
LfgAnswer accept
Accept status (-1 not answer | 0 Not agree | 1 agree)
Definition: LFGMgr.h:349

References lfg::LfgProposalPlayer::accept, lfg::LfgProposal::dungeonId, lfg::LfgProposal::encounters, Object::GetGUID(), GetPlayer(), lfg::LfgProposalPlayer::group, lfg::LfgProposal::group, lfg::LfgProposal::id, lfg::LfgProposal::isNew, lfg::LFG_ANSWER_AGREE, lfg::LFG_ANSWER_PENDING, LOG_DEBUG, lfg::LfgProposal::players, lfg::LfgProposalPlayer::role, SendPacket(), sLFGMgr, SMSG_LFG_PROPOSAL_UPDATE, lfg::LfgProposal::state, and ObjectGuid::ToString().

◆ SendListInventory()

void WorldSession::SendListInventory ( ObjectGuid  guid,
uint32  vendorEntry = 0 
)
1037{
1038 LOG_DEBUG("network", "WORLD: Sent SMSG_LIST_INVENTORY");
1039
1041 if (!vendor)
1042 {
1043 LOG_DEBUG("network", "WORLD: SendListInventory - Unit ({}) not found or you can not interact with him.", vendorGuid.ToString());
1045 return;
1046 }
1047
1048 // remove fake death
1049 if (GetPlayer()->HasUnitState(UNIT_STATE_DIED))
1050 {
1052 }
1053
1054 // Stop the npc if moving
1055 if (uint32 pause = vendor->GetMovementTemplate().GetInteractionPauseTimer())
1056 vendor->PauseMovement(pause);
1057 vendor->SetHomePosition(vendor->GetPosition());
1058
1059 SetCurrentVendor(vendorEntry);
1060
1061 VendorItemData const* items = vendorEntry ? sObjectMgr->GetNpcVendorItemList(vendorEntry) : vendor->GetVendorItems();
1062 if (!items)
1063 {
1064 WorldPacket data(SMSG_LIST_INVENTORY, 8 + 1 + 1);
1065 data << vendorGuid;
1066 data << uint8(0); // count == 0, next will be error code
1067 data << uint8(0); // "Vendor has no inventory"
1068 SendPacket(&data);
1069 return;
1070 }
1071
1072 uint8 itemCount = items->GetItemCount();
1073 uint8 count = 0;
1074
1075 WorldPacket data(SMSG_LIST_INVENTORY, 8 + 1 + itemCount * 8 * 4);
1076 data << vendorGuid;
1077
1078 std::size_t countPos = data.wpos();
1079 data << uint8(count);
1080
1081 float discountMod = _player->GetReputationPriceDiscount(vendor);
1082
1083 for (uint8 slot = 0; slot < itemCount; ++slot)
1084 {
1085 if (VendorItem const* item = items->GetItem(slot))
1086 {
1087 if (ItemTemplate const* itemTemplate = sObjectMgr->GetItemTemplate(item->item))
1088 {
1089 if (!(itemTemplate->AllowableClass & _player->getClassMask()) && itemTemplate->Bonding == BIND_WHEN_PICKED_UP && !_player->IsGameMaster())
1090 {
1091 continue;
1092 }
1093 // Only display items in vendor lists for the team the
1094 // player is on. If GM on, display all items.
1095 if (!_player->IsGameMaster() && ((itemTemplate->HasFlag2(ITEM_FLAG2_FACTION_HORDE) && _player->GetTeamId() == TEAM_ALLIANCE) || (itemTemplate->HasFlag2(ITEM_FLAG2_FACTION_ALLIANCE) && _player->GetTeamId() == TEAM_HORDE)))
1096 {
1097 continue;
1098 }
1099
1100 // Items sold out are not displayed in list
1101 uint32 leftInStock = !item->maxcount ? 0xFFFFFFFF : vendor->GetVendorItemCurrentCount(item);
1102 if (!_player->IsGameMaster() && !leftInStock)
1103 {
1104 continue;
1105 }
1106
1107 ConditionList conditions = sConditionMgr->GetConditionsForNpcVendorEvent(vendor->GetEntry(), item->item);
1108 if (!sConditionMgr->IsObjectMeetToConditions(_player, vendor, conditions))
1109 {
1110 LOG_DEBUG("network", "SendListInventory: conditions not met for creature entry {} item {}", vendor->GetEntry(), item->item);
1111 continue;
1112 }
1113
1114 // reputation discount
1115 int32 price = item->IsGoldRequired(itemTemplate) ? uint32(std::floor(itemTemplate->BuyPrice * discountMod)) : 0;
1116
1117 data << uint32(slot + 1); // client expects counting to start at 1
1118 data << uint32(item->item);
1119 data << uint32(itemTemplate->DisplayInfoID);
1120 data << int32(leftInStock);
1121 data << uint32(price);
1122 data << uint32(itemTemplate->MaxDurability);
1123 data << uint32(itemTemplate->BuyCount);
1124 data << uint32(item->ExtendedCost);
1125
1126 if (++count >= MAX_VENDOR_ITEMS)
1127 {
1128 break;
1129 }
1130 }
1131 }
1132 }
1133
1134 if (count == 0)
1135 {
1136 data << uint8(0);
1137 SendPacket(&data);
1138 return;
1139 }
1140
1141 data.put<uint8>(countPos, count);
1142 SendPacket(&data);
1143}
#define sConditionMgr
Definition: ConditionMgr.h:289
std::list< Condition * > ConditionList
Definition: ConditionMgr.h:236
#define MAX_VENDOR_ITEMS
Definition: Creature.h:43
@ ITEM_FLAG2_FACTION_HORDE
Definition: ItemTemplate.h:183
@ ITEM_FLAG2_FACTION_ALLIANCE
Definition: ItemTemplate.h:184
@ SMSG_LIST_INVENTORY
Definition: Opcodes.h:445
VendorItemData const * GetVendorItems() const
Definition: Creature.cpp:3054
uint32 GetVendorItemCurrentCount(VendorItem const *vItem)
Definition: Creature.cpp:3059
Definition: CreatureData.h:455
Definition: CreatureData.h:470
VendorItem * GetItem(uint32 slot) const
Definition: CreatureData.h:473
uint8 GetItemCount() const
Definition: CreatureData.h:481
uint32 getClassMask() const
Definition: Unit.h:749
void SetCurrentVendor(uint32 vendorEntry)
Definition: WorldSession.h:367

References _player, BIND_WHEN_PICKED_UP, ObjectGuid::Empty, Unit::getClassMask(), Object::GetEntry(), CreatureMovementData::GetInteractionPauseTimer(), VendorItemData::GetItem(), VendorItemData::GetItemCount(), Creature::GetMovementTemplate(), Player::GetNPCIfCanInteractWith(), GetPlayer(), Position::GetPosition(), Player::GetReputationPriceDiscount(), Player::GetTeamId(), Creature::GetVendorItemCurrentCount(), Creature::GetVendorItems(), Player::IsGameMaster(), ITEM_FLAG2_FACTION_ALLIANCE, ITEM_FLAG2_FACTION_HORDE, LOG_DEBUG, MAX_VENDOR_ITEMS, Unit::PauseMovement(), ByteBuffer::put(), Unit::RemoveAurasByType(), sConditionMgr, SELL_ERR_CANT_FIND_VENDOR, SendPacket(), Player::SendSellError(), SetCurrentVendor(), Creature::SetHomePosition(), SMSG_LIST_INVENTORY, sObjectMgr, SPELL_AURA_FEIGN_DEATH, TEAM_ALLIANCE, TEAM_HORDE, ObjectGuid::ToString(), UNIT_NPC_FLAG_VENDOR, UNIT_STATE_DIED, and ByteBuffer::wpos().

Referenced by HandleListInventoryOpcode(), npc_pet_gen_argent_pony_bridle::OnGossipSelect(), npc_lokhtos_darkbargainer::OnGossipSelect(), npc_augustus_the_touched::OnGossipSelect(), npc_rivern_frostwind::OnGossipSelect(), npc_roxi_ramrocket::OnGossipSelect(), npc_wg_quest_giver::OnGossipSelect(), npc_drake_dealer_hurlunk::OnGossipSelect(), npc_shattrathflaskvendors::OnGossipSelect(), npc_slim::OnGossipSelect(), npc_innkeeper::OnGossipSelect(), Player::OnGossipSelect(), npc_prof_alchemy::SendActionMenu(), npc_prof_blacksmith::SendActionMenu(), and npc_prof_tailor::SendActionMenu().

◆ SendNameQueryOpcode()

void WorldSession::SendNameQueryOpcode ( ObjectGuid  guid)
32{
33 CharacterCacheEntry const* playerData = sCharacterCache->GetCharacterCacheByGuid(guid);
34
35 WorldPacket data(SMSG_NAME_QUERY_RESPONSE, (8 + 1 + 1 + 1 + 1 + 1 + 10));
36 data << guid.WriteAsPacked();
37 if (!playerData)
38 {
39 data << uint8(1); // name unknown
40 SendPacket(&data);
41 return;
42 }
43
45
46 data << uint8(0); // name known
47 data << playerData->Name; // played name
48 data << uint8(0); // realm name - only set for cross realm interaction (such as Battlegrounds)
49 data << uint8(player ? player->getRace() : playerData->Race);
50 data << uint8(playerData->Sex);
51 data << uint8(playerData->Class);
52
53 // pussywizard: optimization
54 /*Player* player = ObjectAccessor::FindConnectedPlayer(guid);
55 if (DeclinedName const* names = (player ? player->GetDeclinedNames() : nullptr))
56 {
57 data << uint8(1); // Name is declined
58 for (uint8 i = 0; i < MAX_DECLINED_NAME_CASES; ++i)
59 data << names->name[i];
60 }
61 else*/
62 data << uint8(0); // Name is not declined
63
64 SendPacket(&data);
65}
@ SMSG_NAME_QUERY_RESPONSE
Definition: Opcodes.h:111
uint8 Sex
Definition: CharacterCache.h:34

References CharacterCacheEntry::Class, ObjectAccessor::FindConnectedPlayer(), Unit::getRace(), CharacterCacheEntry::Name, CharacterCacheEntry::Race, sCharacterCache, SendPacket(), CharacterCacheEntry::Sex, SMSG_NAME_QUERY_RESPONSE, and ObjectGuid::WriteAsPacked().

Referenced by HandleNameQueryOpcode(), HandlePlayerLoginFromDB(), and lfg::LFGPlayerScript::OnMapChanged().

◆ SendNotInArenaTeamPacket()

void WorldSession::SendNotInArenaTeamPacket ( uint8  type)
417{
418 WorldPacket data(SMSG_ARENA_ERROR, 4 + 1); // 886 - You are not in a %uv%u arena team
419 uint32 unk = 0;
420 data << uint32(unk); // unk(0)
421 if (!unk)
422 data << uint8(type); // team type (2=2v2, 3=3v3, 5=5v5), can be used for custom types...
423 SendPacket(&data);
424}
@ SMSG_ARENA_ERROR
Definition: Opcodes.h:916

References SendPacket(), and SMSG_ARENA_ERROR.

Referenced by HandleBattlemasterJoinArena().

◆ SendPacket()

void WorldSession::SendPacket ( WorldPacket const *  packet)

Send a packet to the client.

215{
216 if (!m_Socket)
217 return;
218
219#if defined(ACORE_DEBUG)
220 // Code for network use statistic
221 static uint64 sendPacketCount = 0;
222 static uint64 sendPacketBytes = 0;
223
224 static time_t firstTime = GameTime::GetGameTime().count();
225 static time_t lastTime = firstTime; // next 60 secs start time
226
227 static uint64 sendLastPacketCount = 0;
228 static uint64 sendLastPacketBytes = 0;
229
230 time_t cur_time = GameTime::GetGameTime().count();
231
232 if ((cur_time - lastTime) < 60)
233 {
234 sendPacketCount += 1;
235 sendPacketBytes += packet->size();
236
237 sendLastPacketCount += 1;
238 sendLastPacketBytes += packet->size();
239 }
240 else
241 {
242 uint64 minTime = uint64(cur_time - lastTime);
243 uint64 fullTime = uint64(lastTime - firstTime);
244
245 LOG_DEBUG("network", "Send all time packets count: {} bytes: {} avr.count/sec: {} avr.bytes/sec: {} time: {}", sendPacketCount, sendPacketBytes, float(sendPacketCount) / fullTime, float(sendPacketBytes) / fullTime, uint32(fullTime));
246
247 LOG_DEBUG("network", "Send last min packets count: {} bytes: {} avr.count/sec: {} avr.bytes/sec: {}", sendLastPacketCount, sendLastPacketBytes, float(sendLastPacketCount) / minTime, float(sendLastPacketBytes) / minTime);
248
249 lastTime = cur_time;
250 sendLastPacketCount = 1;
251 sendLastPacketBytes = packet->wpos(); // wpos is real written size
252 }
253#endif // !ACORE_DEBUG
254
255 if (!sScriptMgr->CanPacketSend(this, *packet))
256 {
257 return;
258 }
259
260 m_Socket->SendPacket(*packet);
261}

References GameTime::GetGameTime(), LOG_DEBUG, m_Socket, ByteBuffer::size(), sScriptMgr, and ByteBuffer::wpos().

Referenced by Pet::_LoadSpellCooldowns(), Guild::_SendBankList(), Player::_StoreOrEquipNewItem(), InstanceMap::AddPlayerToMap(), Player::AddRunePower(), Player::addSpell(), Player::ApplyEquipCooldown(), TotemAI::AttackStart(), Player::BindToInstance(), Group::BroadcastPacket(), Group::BroadcastReadyCheck(), SocialMgr::BroadcastToFriendListers(), Player::BuildPlayerRepop(), Player::CharmSpellInitialize(), Player::CheckDuelDistance(), Player::ConvertRune(), Object::DestroyForPlayer(), Group::Disband(), Spell::EffectDuel(), Spell::EffectSummonPlayer(), Spell::EffectSummonRaFFriend(), Player::EquipItem(), AuctionListItemsDelayEvent::Execute(), BGQueueInviteEvent::Execute(), SendEncounterUnit::Execute(), Player::GetAurasForTarget(), ChannelMgr::GetChannel(), HandleAlterAppearance(), HandleArenaTeamInviteOpcode(), HandleAuctionListBidderItems(), HandleAuctionListOwnerItemsEvent(), HandleAuctionListPendingSales(), AuraEffect::HandleAuraSetVehicle(), HandleBattlefieldListOpcode(), HandleBattleFieldPortOpcode(), HandleBattlefieldStatusOpcode(), HandleBattlegroundPlayerPositionsOpcode(), HandleBattlemasterJoinArena(), HandleBattlemasterJoinOpcode(), HandleBuyBankSlotOpcode(), HandleCalendarGetCalendar(), HandleCalendarGetNumPending(), HandleCharCustomize(), HandleCharEnum(), HandleChatIgnoredOpcode(), HandleComplainOpcode(), HandleCorpseMapPositionQuery(), HandleCorpseQueryOpcode(), HandleCreatureQueryOpcode(), debug_commandscript::HandleDebugSendChannelNotifyCommand(), debug_commandscript::HandleDebugSendChatMsgCommand(), debug_commandscript::HandleDebugSendOpcodeCommand(), debug_commandscript::HandleDebugSendSpellFailCommand(), spell_gen_spirit_healer_res::HandleDummy(), HandleEquipmentSetUse(), HandleGameObjectQueryOpcode(), HandleGetChannelMemberCount(), HandleGetMailList(), HandleGMResponseResolve(), HandleGMTicketCreateOpcode(), HandleGMTicketDeleteOpcode(), HandleGMTicketSystemStatusOpcode(), HandleGMTicketUpdateOpcode(), HandleGrantLevel(), HandleGroupDeclineOpcode(), HandleGroupInviteOpcode(), HandleInitiateTradeOpcode(), HandleInspectHonorStatsOpcode(), HandleInspectOpcode(), HandleItemNameQueryOpcode(), HandleItemQuerySingleOpcode(), HandleItemTextQuery(), HandleLfgPartyLockInfoRequestOpcode(), HandleLfgPlayerLockInfoRequestOpcode(), HandleLogoutCancelOpcode(), HandleLogoutRequestOpcode(), HandleLootMoneyOpcode(), HandleMirrorImageDataRequest(), modify_commandscript::HandleModifySpellCommand(), HandleNpcTextQueryOpcode(), HandleOfferPetitionOpcode(), HandlePageTextQueryOpcode(), HandlePetActionHelper(), HandlePetitionRenameOpcode(), HandlePetitionShowSignOpcode(), HandlePetitionSignOpcode(), HandlePlayedTime(), HandlePlayerLoginFromDB(), HandlePlayerLoginOpcode(), HandlePlayerLoginToCharInWorld(), HandlePVPLogDataOpcode(), Guild::HandleQuery(), HandleQueryNextMailTime(), HandleQueryQuestsCompleted(), HandleQuestPOIQuery(), HandleReadItem(), HandleRealmSplitOpcode(), HandleRequestAccountData(), HandleRequestPartyMemberStatsOpcode(), Guild::HandleRoster(), spell_pvp_trinket_wotf_shared_cd::HandleScript(), misc_commandscript::HandleSkirmishCommand(), HandleTalentWipeConfirmOpcode(), HandleTrainerBuySpellOpcode(), HandleTurnInPetitionOpcode(), HandleUpdateAccountData(), HandleWhoisOpcode(), HandleWhoOpcode(), HandleWorldStateUITimerUpdate(), WardenWin::InitializeModule(), ArenaTeam::Inspect(), BattlegroundQueue::InviteGroupToBG(), Unit::JumpTo(), Unit::KnockbackFrom(), LogoutPlayer(), ArenaTeam::MassInviteToEvent(), Guild::MassInviteToEvent(), GameObject::ModifyHealth(), Player::ModifySpellCooldown(), npc_wg_demolisher_engineer::OnGossipSelect(), InstanceMap::PermBindAllPlayers(), Player::PetSpellInitialize(), Battleground::PlayerAddedToBGCheckIfBGIsRunning(), MapMgr::PlayerCannotEnter(), Player::PossessSpellInitialize(), Player::ProhibitSpellSchool(), ArenaTeam::Query(), Player::RefundItem(), Group::RemoveMember(), Player::RemovePet(), Battleground::RemovePlayerAtLeave(), Player::RepopAtGraveyard(), WardenMac::RequestChecks(), WardenWin::RequestChecks(), WardenMac::RequestHash(), WardenWin::RequestHash(), Warden::RequestModule(), Player::ResurrectPlayer(), Player::ResyncRunes(), Player::RewardHonor(), ArenaTeam::Roster(), Player::SatisfyQuestLog(), AddonChannelCommandHandler::Send(), SendAccountDataTimes(), Player::SendActionButtons(), SendActivateTaxiReply(), SendAddonsInfo(), AchievementMgr::SendAllAchievementData(), BattlegroundMgr::SendAreaSpiritHealerQueryOpcode(), Battlefield::SendAreaSpiritHealerQueryOpcode(), SendAreaTriggerMessage(), SendArenaTeamCommandResult(), SendAttackStop(), Player::SendAttackSwingBadFacingAttack(), Player::SendAttackSwingCancelAttack(), Player::SendAttackSwingCantAttack(), Player::SendAttackSwingDeadTarget(), Player::SendAttackSwingNotInRange(), SendAuctionBidderNotification(), SendAuctionCommandResult(), SendAuctionHello(), SendAuctionOwnerNotification(), SendAuthResponse(), SendAuthWaitQueue(), Guild::SendBankLog(), SendBattleGroundList(), SendBfEntered(), SendBfInvitePlayerToQueue(), SendBfInvitePlayerToWar(), SendBfLeaveMessage(), SendBfQueueInviteResponse(), SendBindPoint(), Player::SendBuyError(), SendCalendarRaidLockout(), SendCalendarRaidLockoutUpdated(), Player::SendCanTakeQuestResponse(), Spell::SendCastResult(), SendCharCreate(), SendCharCustomize(), SendCharDelete(), SendCharFactionChange(), SendCharRename(), SendChatRestrictedNotice(), SendClientCacheVersion(), PlayerMenu::SendCloseGossip(), Guild::SendCommandResult(), Player::SendCorpseReclaimDelay(), Player::SendDirectMessage(), SendDiscoverNewTaxiNode(), Player::SendDuelCountdown(), Player::SendDungeonDifficulty(), Player::SendEquipError(), Player::SendEquipmentSetList(), Guild::SendEventLog(), Player::SendExplorationExperience(), SocialMgr::SendFriendStatus(), ChatHandler::SendGMText(), PlayerMenu::SendGossipMenu(), Guild::SendInfo(), Player::SendInitialPacketsBeforeAddToMap(), Player::SendInitialSpells(), Map::SendInitTransports(), Player::SendInitWorldStates(), BattlefieldWG::SendInitWorldStatesTo(), Player::SendInstanceResetWarning(), SendItemEnchantTimeUpdate(), SendLearnNewTaxiNode(), Player::SendLearnPacket(), SendLfgBootProposalUpdate(), SendLfgDisabled(), SendLfgJoinResult(), SendLfgLfrList(), SendLfgOfferContinue(), SendLfgPlayerReward(), SendLfgQueueStatus(), SendLfgRoleCheckUpdate(), SendLfgRoleChosen(), SendLfgTeleportError(), SendLfgUpdateParty(), SendLfgUpdatePlayer(), SendLfgUpdateProposal(), SendListInventory(), Guild::SendLoginInfo(), Player::SendLogXPGain(), Group::SendLootAllPassed(), Group::SendLootRoll(), Group::SendLootRollWon(), Group::SendLootStartRoll(), Group::SendLootStartRollToPlayer(), Player::SendMailResult(), Warden::SendModuleToClient(), Guild::SendMoneyInfo(), SendNameQueryOpcode(), Player::SendNewItem(), Player::SendNewMail(), CreatureTextMgr::SendNonChatPacket(), ChatHandler::SendNotification(), Player::SendNotifyLootItemRemoved(), Player::SendNotifyLootMoneyRemoved(), SendNotInArenaTeamPacket(), Acore::MessageDistDeliverer::SendPacket(), Acore::MessageDistDelivererToHostile::SendPacket(), SendPartyResult(), Guild::SendPermissions(), Unit::SendPetActionFeedback(), Unit::SendPetAIReaction(), Spell::SendPetCastResult(), SendPetitionQueryOpcode(), SendPetitionShowList(), SendPetNameInvalid(), SendPetNameQuery(), Unit::SendPetTalk(), SendPlayerAmbiguousNotice(), SendPlayerNotFoundNotice(), WorldObject::SendPlayMusic(), PlayerMenu::SendPointOfInterest(), Player::SendProficiency(), Player::SendPushToPartyResponse(), SendQueryTimeResponse(), Player::SendQuestComplete(), Player::SendQuestConfirmAccept(), Player::SendQuestFailed(), PlayerMenu::SendQuestGiverOfferReward(), PlayerMenu::SendQuestGiverQuestDetails(), PlayerMenu::SendQuestGiverQuestList(), PlayerMenu::SendQuestGiverRequestItems(), PlayerMenu::SendQuestGiverStatus(), Player::SendQuestGiverStatusMultiple(), PlayerMenu::SendQuestQueryResponse(), Player::SendQuestReward(), Player::SendQuestTimerFailed(), Player::SendQuestUpdateAddCreatureOrGo(), Player::SendQuestUpdateAddItem(), Player::SendQuestUpdateAddPlayer(), lfg::LFGMgr::SendRaidBrowserCachedList(), Player::SendRaidDifficulty(), Player::SendRaidInfo(), Player::SendRefundInfo(), Player::SendRemoveControlBar(), Map::SendRemoveTransports(), Player::SendResetFailedNotify(), Player::SendResetInstanceFailed(), Player::SendResetInstanceSuccess(), AchievementMgr::SendRespondInspectAchievements(), GmTicket::SendResponse(), Spell::SendResurrectRequest(), Player::SendSavedInstances(), Guild::SendSaveEmblemResult(), Player::SendSellError(), SendSetPhaseShift(), SendSetPlayerDeclinedNamesResult(), SendShowBank(), SendShowMailBox(), PlayerSocial::SendSocialList(), SendStablePet(), SendStableResult(), ArenaTeam::SendStats(), ChatHandler::SendSysMessage(), SendTabardVendorActivate(), Player::SendTalentsInfoData(), Player::SendTalentWipeConfirm(), Group::SendTargetIconList(), SendTaxiMenu(), SendTaxiStatus(), Player::SendTeleportAckPacket(), Guild::BankTab::SendText(), TicketMgr::SendTicket(), SendTimeSync(), Item::SendTimeUpdate(), Acore::VisibleNotifier::SendToSelf(), SendTradeStatus(), SendTrainerList(), Player::SendTransferAborted(), BattlegroundSA::SendTransportInit(), BattlegroundSA::SendTransportsRemove(), SendTutorialsData(), Item::SendUpdateSockets(), Group::SendUpdateToPlayer(), Object::SendUpdateToPlayer(), SendUpdateTrade(), SendWrongFactionNotice(), Player::SetBindPoint(), Player::SetClientControl(), Player::SetEquipmentSet(), Player::SetMovement(), Unit::SetStandState(), Player::SetTitle(), Player::TeleportTo(), GameObject::Update(), Player::UpdateForQuestWorldObjects(), Player::UpdateHomebindTime(), Group::UpdatePlayerOutOfRange(), Player::UpdateTriggerVisibility(), GameObject::Use(), Player::VehicleSpellInitialize(), and Player::Whisper().

◆ SendPartyResult()

void WorldSession::SendPartyResult ( PartyOperation  operation,
std::string const &  member,
PartyResult  res,
uint32  val = 0 
)
53{
54 WorldPacket data(SMSG_PARTY_COMMAND_RESULT, 4 + member.size() + 1 + 4 + 4);
55 data << uint32(operation);
56 data << member;
57 data << uint32(res);
58 data << uint32(val); // LFD cooldown related (used with ERR_PARTY_LFG_BOOT_COOLDOWN_S and ERR_PARTY_LFG_BOOT_NOT_ELIGIBLE_S)
59
60 SendPacket(&data);
61}
@ SMSG_PARTY_COMMAND_RESULT
Definition: Opcodes.h:157

References SendPacket(), and SMSG_PARTY_COMMAND_RESULT.

Referenced by HandleGroupAcceptOpcode(), HandleGroupDisbandOpcode(), HandleGroupInviteOpcode(), HandleGroupRaidConvertOpcode(), HandleGroupSwapSubGroupOpcode(), HandleGroupUninviteGuidOpcode(), and HandleGroupUninviteOpcode().

◆ SendPetitionQueryOpcode()

void WorldSession::SendPetitionQueryOpcode ( ObjectGuid  petitionguid)
279{
280 Petition const* petition = sPetitionMgr->GetPetition(petitionguid);
281 if (!petition)
282 {
283 LOG_DEBUG("network", "CMSG_PETITION_QUERY failed for petition ({})", petitionguid.ToString());
284 return;
285 }
286
287 uint8 type = petition->petitionType;
288 WorldPacket data(SMSG_PETITION_QUERY_RESPONSE, (4 + 8 + petition->petitionName.size() + 1 + 1 + 4 * 12 + 2 + 10));
289 data << uint32(petitionguid.GetCounter()); // guild/team guid (in Trinity always same as petition low guid
290 data << petition->ownerGuid; // charter owner guid
291 data << petition->petitionName; // name (guild/arena team)
292 data << uint8(0); // some string
293 if (type == GUILD_CHARTER_TYPE)
294 {
295 uint32 needed = sWorld->getIntConfig(CONFIG_MIN_PETITION_SIGNS);
296 data << uint32(needed);
297 data << uint32(needed);
298 data << uint32(0); // bypass client - side limitation, a different value is needed here for each petition
299 }
300 else
301 {
302 data << uint32(type - 1);
303 data << uint32(type - 1);
304 data << uint32(type); // bypass client - side limitation, a different value is needed here for each petition
305 }
306 data << uint32(0); // 5
307 data << uint32(0); // 6
308 data << uint32(0); // 7
309 data << uint32(0); // 8
310 data << uint16(0); // 9 2 bytes field
311 data << uint32(0); // 10
312 data << uint32(0); // 11
313 data << uint32(0); // 13 count of next strings?
314
315 for (int i = 0; i < 10; ++i)
316 data << uint8(0); // some string
317
318 data << uint32(0); // 14
319
320 data << uint32(type != GUILD_CHARTER_TYPE); // 15 0 - guild, 1 - arena team
321
322 SendPacket(&data);
323}
@ SMSG_PETITION_QUERY_RESPONSE
Definition: Opcodes.h:485

References CONFIG_MIN_PETITION_SIGNS, ObjectGuid::GetCounter(), GUILD_CHARTER_TYPE, LOG_DEBUG, Petition::ownerGuid, Petition::petitionName, Petition::petitionType, SendPacket(), SMSG_PETITION_QUERY_RESPONSE, sPetitionMgr, sWorld, and ObjectGuid::ToString().

Referenced by HandlePetitionQueryOpcode(), and Player::RemovePetitionsAndSigns().

◆ SendPetitionShowList()

void WorldSession::SendPetitionShowList ( ObjectGuid  guid)
825{
827 if (!creature)
828 {
829 LOG_DEBUG("network", "WORLD: HandlePetitionShowListOpcode - Unit ({}) not found or you can't interact with him.", guid.ToString());
830 return;
831 }
832
833 WorldPacket data(SMSG_PETITION_SHOWLIST, 8 + 1 + 4 * 6);
834 data << guid; // npc guid
835
836 // For guild default
837 uint32 CharterEntry = GUILD_CHARTER;
838 uint32 CharterDispayID = CHARTER_DISPLAY_ID;
839 uint32 CharterCost = sWorld->getIntConfig(CONFIG_CHARTER_COST_GUILD);
840
841 if (creature->IsTabardDesigner())
842 {
843 sScriptMgr->PetitionShowList(_player, creature, CharterEntry, CharterDispayID, CharterCost);
844
845 data << uint8(1); // count
846 data << uint32(1); // index
847 data << CharterEntry; // charter entry
848 data << CharterDispayID; // charter display id
849 data << CharterCost; // charter cost
850 data << uint32(0); // unknown
851 data << uint32(sWorld->getIntConfig(CONFIG_MIN_PETITION_SIGNS)); // required signs
852 }
853 else
854 {
855 // For 2v2 default
856 CharterEntry = ARENA_TEAM_CHARTER_2v2;
857 CharterDispayID = CHARTER_DISPLAY_ID;
858 CharterCost = sWorld->getIntConfig(CONFIG_CHARTER_COST_ARENA_2v2);
859
860 // 2v2
861 data << uint8(3); // count
862 sScriptMgr->PetitionShowList(_player, creature, CharterEntry, CharterDispayID, CharterCost);
863 data << uint32(1); // index
864 data << CharterEntry; // charter entry
865 data << CharterDispayID; // charter display id
866 data << CharterCost; // charter cost
867 data << uint32(2); // unknown
868 data << uint32(2); // required signs?
869
870 // For 3v3 default
871 CharterEntry = ARENA_TEAM_CHARTER_3v3;
872 CharterDispayID = CHARTER_DISPLAY_ID;
873 CharterCost = sWorld->getIntConfig(CONFIG_CHARTER_COST_ARENA_3v3);
874
875 // 3v3
876 sScriptMgr->PetitionShowList(_player, creature, CharterEntry, CharterDispayID, CharterCost);
877 data << uint32(2); // index
878 data << CharterEntry; // charter entry
879 data << CharterDispayID; // charter display id
880 data << CharterCost; // charter cost
881 data << uint32(3); // unknown
882 data << uint32(3); // required signs?
883
884 // For 3v3 default
885 CharterEntry = ARENA_TEAM_CHARTER_5v5;
886 CharterDispayID = CHARTER_DISPLAY_ID;
887 CharterCost = sWorld->getIntConfig(CONFIG_CHARTER_COST_ARENA_5v5);
888
889 // 5v5
890 sScriptMgr->PetitionShowList(_player, creature, CharterEntry, CharterDispayID, CharterCost);
891 data << uint32(3); // index
892 data << CharterEntry; // charter entry
893 data << CharterDispayID; // charter display id
894 data << CharterCost; // charter cost
895 data << uint32(5); // unknown
896 data << uint32(5); // required signs?
897 }
898
899 SendPacket(&data);
900 LOG_DEBUG("network", "Sent SMSG_PETITION_SHOWLIST");
901}
#define CHARTER_DISPLAY_ID
Definition: PetitionMgr.h:26
@ SMSG_PETITION_SHOWLIST
Definition: Opcodes.h:474

References _player, ARENA_TEAM_CHARTER_2v2, ARENA_TEAM_CHARTER_3v3, ARENA_TEAM_CHARTER_5v5, CHARTER_DISPLAY_ID, CONFIG_CHARTER_COST_ARENA_2v2, CONFIG_CHARTER_COST_ARENA_3v3, CONFIG_CHARTER_COST_ARENA_5v5, CONFIG_CHARTER_COST_GUILD, CONFIG_MIN_PETITION_SIGNS, Player::GetNPCIfCanInteractWith(), GetPlayer(), GUILD_CHARTER, Unit::IsTabardDesigner(), LOG_DEBUG, SendPacket(), SMSG_PETITION_SHOWLIST, sScriptMgr, sWorld, ObjectGuid::ToString(), and UNIT_NPC_FLAG_PETITIONER.

Referenced by HandlePetitionShowListOpcode(), and Player::OnGossipSelect().

◆ SendPetNameInvalid()

void WorldSession::SendPetNameInvalid ( uint32  error,
std::string const &  name,
DeclinedName declinedName 
)
1091{
1092 WorldPacket data(SMSG_PET_NAME_INVALID, 4 + name.size() + 1 + 1);
1093 data << uint32(error);
1094 data << name;
1095 if (declinedName)
1096 {
1097 data << uint8(1);
1098 for (uint32 i = 0; i < MAX_DECLINED_NAME_CASES; ++i)
1099 data << declinedName->name[i];
1100 }
1101 else
1102 data << uint8(0);
1103 SendPacket(&data);
1104}
@ SMSG_PET_NAME_INVALID
Definition: Opcodes.h:406

References MAX_DECLINED_NAME_CASES, DeclinedName::name, SendPacket(), and SMSG_PET_NAME_INVALID.

Referenced by HandlePetRename().

◆ SendPetNameQuery()

void WorldSession::SendPetNameQuery ( ObjectGuid  guid,
uint32  petnumber 
)
608{
610 if (!pet)
611 {
612 WorldPacket data(SMSG_PET_NAME_QUERY_RESPONSE, (4 + 1 + 4 + 1));
613 data << uint32(petnumber);
614 data << uint8(0);
615 data << uint32(0);
616 data << uint8(0);
617 SendPacket(&data);
618 return;
619 }
620
621 std::string name;
623 {
624 // Use localized creature name for the mage pet
626 if (loc_idx != DEFAULT_LOCALE)
627 name = pet->GetNameForLocaleIdx(loc_idx);
628 else
629 name = pet->GetCreatureTemplate()->Name;
630 }
631 else
632 name = pet->GetName();
633
634 WorldPacket data(SMSG_PET_NAME_QUERY_RESPONSE, (4 + 4 + name.size() + 1));
635 data << uint32(petnumber);
636 data << name.c_str();
638
639 if (pet->IsPet() && ((Pet*)pet)->GetDeclinedNames())
640 {
641 data << uint8(1);
642 for (uint8 i = 0; i < MAX_DECLINED_NAME_CASES; ++i)
643 data << ((Pet*)pet)->GetDeclinedNames()->name[i];
644 }
645 else
646 data << uint8(0);
647
648 SendPacket(&data);
649}
@ NPC_WATER_ELEMENTAL_PERM
Definition: PetDefines.h:106
@ SMSG_PET_NAME_QUERY_RESPONSE
Definition: Opcodes.h:113
std::string const & GetNameForLocaleIdx(LocaleConstant locale_idx) const override
Definition: Creature.cpp:3137

References _player, DEFAULT_LOCALE, ObjectAccessor::GetCreatureOrPetOrVehicle(), Creature::GetCreatureTemplate(), Object::GetEntry(), WorldObject::GetName(), Creature::GetNameForLocaleIdx(), GetSessionDbLocaleIndex(), Object::GetUInt32Value(), Unit::IsPet(), MAX_DECLINED_NAME_CASES, CreatureTemplate::Name, NPC_WATER_ELEMENTAL_PERM, SendPacket(), SMSG_PET_NAME_QUERY_RESPONSE, and UNIT_FIELD_PET_NAME_TIMESTAMP.

Referenced by HandlePetNameQuery().

◆ SendPlayerAmbiguousNotice()

void WorldSession::SendPlayerAmbiguousNotice ( std::string const &  name)
831{
832 WorldPacket data(SMSG_CHAT_PLAYER_AMBIGUOUS, name.size() + 1);
833 data << name;
834 SendPacket(&data);
835}
@ SMSG_CHAT_PLAYER_AMBIGUOUS
Definition: Opcodes.h:843

References SendPacket(), and SMSG_CHAT_PLAYER_AMBIGUOUS.

◆ SendPlayerNotFoundNotice()

void WorldSession::SendPlayerNotFoundNotice ( std::string const &  name)
824{
825 WorldPacket data(SMSG_CHAT_PLAYER_NOT_FOUND, name.size() + 1);
826 data << name;
827 SendPacket(&data);
828}
@ SMSG_CHAT_PLAYER_NOT_FOUND
Definition: Opcodes.h:711

References SendPacket(), and SMSG_CHAT_PLAYER_NOT_FOUND.

Referenced by HandleMessagechatOpcode().

◆ SendQueryTimeResponse()

void WorldSession::SendQueryTimeResponse ( )
84{
85 auto timeResponse = sWorld->GetNextDailyQuestsResetTime() - GameTime::GetGameTime();
86
88 data << uint32(GameTime::GetGameTime().count());
89 data << uint32(timeResponse.count());
90 SendPacket(&data);
91}
@ SMSG_QUERY_TIME_RESPONSE
Definition: Opcodes.h:493

References GameTime::GetGameTime(), SendPacket(), SMSG_QUERY_TIME_RESPONSE, and sWorld.

Referenced by HandleGMTicketGetTicketOpcode(), and HandleQueryTimeOpcode().

◆ SendSetPhaseShift()

void WorldSession::SendSetPhaseShift ( uint32  phaseShift)
1652{
1654 data << uint32(PhaseShift);
1655 SendPacket(&data);
1656}
@ SMSG_SET_PHASE_SHIFT
Definition: Opcodes.h:1178

References SendPacket(), and SMSG_SET_PHASE_SHIFT.

Referenced by debug_commandscript::HandleDebugSendSetPhaseShiftCommand().

◆ SendSetPlayerDeclinedNamesResult()

void WorldSession::SendSetPlayerDeclinedNamesResult ( DeclinedNameResult  result,
ObjectGuid  guid 
)
2623{
2625 data << uint32(result);
2626 data << guid;
2627 SendPacket(&data);
2628}
@ SMSG_SET_PLAYER_DECLINED_NAMES_RESULT
Definition: Opcodes.h:1080

References SendPacket(), and SMSG_SET_PLAYER_DECLINED_NAMES_RESULT.

Referenced by HandleSetPlayerDeclinedNames().

◆ SendShowBank()

void WorldSession::SendShowBank ( ObjectGuid  guid)

◆ SendShowMailBox()

void WorldSession::SendShowMailBox ( ObjectGuid  guid)
73{
75 data << guid;
76 SendPacket(&data);
77}
@ SMSG_SHOW_MAILBOX
Definition: Opcodes.h:693

References SendPacket(), and SMSG_SHOW_MAILBOX.

Referenced by misc_commandscript::HandleMailBoxCommand(), and npc_pet_gen_argent_pony_bridle::OnGossipSelect().

◆ SendSpiritResurrect()

void WorldSession::SendSpiritResurrect ( )
388{
389 _player->ResurrectPlayer(0.5f, true);
390
391 _player->DurabilityLossAll(0.25f, true);
392
393 // get corpse nearest graveyard
394 GraveyardStruct const* corpseGrave = nullptr;
395
396 // Search for any graveyards near the player's corpse.
397 corpseGrave = sGraveyard->GetClosestGraveyard(_player, _player->GetTeamId(), _player->HasCorpse());
398
399 // now can spawn bones
401
402 // teleport to nearest from corpse graveyard, if different from nearest to player ghost
403 if (corpseGrave)
404 {
405 GraveyardStruct const* ghostGrave = sGraveyard->GetClosestGraveyard(_player, _player->GetTeamId());
406
407 if (corpseGrave != ghostGrave)
408 _player->TeleportTo(corpseGrave->Map, corpseGrave->x, corpseGrave->y, corpseGrave->z, _player->GetOrientation());
409 // or update at original position
410 //else
411 // _player->UpdateObjectVisibility(); // xinef: not needed, called in ResurrectPlayer
412 }
413 // or update at original position
414 //else
415 // _player->UpdateObjectVisibility(); // xinef: not needed, called in ResurrectPlayer
416}
void DurabilityLossAll(double percent, bool inventory)
Definition: Player.cpp:4702

References _player, Player::DurabilityLossAll(), Position::GetOrientation(), Player::GetTeamId(), Player::HasCorpse(), GraveyardStruct::Map, Player::ResurrectPlayer(), sGraveyard, Player::SpawnCorpseBones(), Player::TeleportTo(), GraveyardStruct::x, GraveyardStruct::y, and GraveyardStruct::z.

Referenced by HandleSpiritHealerActivateOpcode().

◆ SendStablePet()

void WorldSession::SendStablePet ( ObjectGuid  guid)
481{
482 LOG_DEBUG("network", "WORLD: Recv MSG_LIST_STABLED_PETS Send.");
483
484 WorldPacket data(MSG_LIST_STABLED_PETS, 200); // guess size
485 data << guid;
486 std::size_t wpos = data.wpos();
487 data << uint8(0); // place holder for slot show number
488
489 PetStable* petStable = GetPlayer()->GetPetStable();
490 if (!petStable)
491 {
492 data << uint8(0); // stable slots
493 SendPacket(&data);
494 return;
495 }
496
497 data << uint8(petStable->MaxStabledPets);
498
499 uint8 num = 0; // counter for place holder
500
501 // not let move dead pet in slot
502 if (petStable->CurrentPet)
503 {
504 PetStable::PetInfo const& pet = *petStable->CurrentPet;
505 data << uint32(pet.PetNumber);
506 data << uint32(pet.CreatureId);
507 data << uint32(pet.Level);
508 data << pet.Name; // petname
509 data << uint8(1); // flags: 1 active, 2 inactive
510 ++num;
511 }
512 else
513 {
514 if (PetStable::PetInfo const* pet = petStable->GetUnslottedHunterPet())
515 {
516 data << uint32(pet->PetNumber);
517 data << uint32(pet->CreatureId);
518 data << uint32(pet->Level);
519 data << pet->Name; // petname
520 data << uint8(1); // flags: 1 active, 2 inactive
521 ++num;
522 }
523 }
524
525 for (Optional<PetStable::PetInfo> const& stabledSlot : petStable->StabledPets)
526 {
527 if (stabledSlot)
528 {
529 PetStable::PetInfo const& pet = *stabledSlot;
530 data << uint32(pet.PetNumber);
531 data << uint32(pet.CreatureId);
532 data << uint32(pet.Level);
533 data << pet.Name; // petname
534 data << uint8(2); // flags: 1 active, 2 inactive
535 ++num;
536 }
537 }
538
539 data.put<uint8>(wpos, num); // set real data to placeholder
540 SendPacket(&data);
541}
@ MSG_LIST_STABLED_PETS
Definition: Opcodes.h:653
PetInfo const * GetUnslottedHunterPet() const
Definition: PetDefines.h:230
Definition: PetDefines.h:205
uint32 CreatureId
Definition: PetDefines.h:211
uint8 Level
Definition: PetDefines.h:219
std::string Name
Definition: PetDefines.h:208
uint32 PetNumber
Definition: PetDefines.h:210

References PetStable::PetInfo::CreatureId, PetStable::CurrentPet, Player::GetPetStable(), GetPlayer(), PetStable::GetUnslottedHunterPet(), PetStable::PetInfo::Level, LOG_DEBUG, PetStable::MaxStabledPets, MSG_LIST_STABLED_PETS, PetStable::PetInfo::Name, PetStable::PetInfo::PetNumber, ByteBuffer::put(), SendPacket(), PetStable::StabledPets, and ByteBuffer::wpos().

Referenced by AuraEffect::HandleAuraOpenStable(), HandleListStabledPetsOpcode(), and Player::OnGossipSelect().

◆ SendStablePetCallback()

void WorldSession::SendStablePetCallback ( ObjectGuid  guid,
PreparedQueryResult  result 
)

◆ SendStableResult()

void WorldSession::SendStableResult ( uint8  guid)
544{
546 data << uint8(res);
547 SendPacket(&data);
548}
@ SMSG_STABLE_RESULT
Definition: Opcodes.h:657

References SendPacket(), and SMSG_STABLE_RESULT.

Referenced by HandleBuyStableSlot(), HandleStablePet(), HandleStableSwapPet(), and HandleUnstablePet().

◆ SendTabardVendorActivate()

void WorldSession::SendTabardVendorActivate ( ObjectGuid  guid)
66{
68 data << guid;
69 SendPacket(&data);
70}
@ MSG_TABARDVENDOR_ACTIVATE
Definition: Opcodes.h:528

References MSG_TABARDVENDOR_ACTIVATE, and SendPacket().

Referenced by HandleTabardVendorActivateOpcode(), and Player::OnGossipSelect().

◆ SendTaxiMenu()

void WorldSession::SendTaxiMenu ( Creature unit)
85{
86 // find current node
87 uint32 curloc = sObjectMgr->GetNearestTaxiNode(unit->GetPositionX(), unit->GetPositionY(), unit->GetPositionZ(), unit->GetMapId(), GetPlayer()->GetTeamId());
88
89 if (curloc == 0)
90 return;
91
92 bool lastTaxiCheaterState = GetPlayer()->isTaxiCheater();
93 if (unit->GetEntry() == 29480) GetPlayer()->SetTaxiCheater(true); // Grimwing in Ebon Hold, special case. NOTE: Not perfect, Zul'Aman should not be included according to WoWhead, and I think taxicheat includes it.
94
95 LOG_DEBUG("network", "WORLD: CMSG_TAXINODE_STATUS_QUERY {} ", curloc);
96
97 WorldPacket data(SMSG_SHOWTAXINODES, (4 + 8 + 4 + 8 * 4));
98 data << uint32(1);
99 data << unit->GetGUID();
100 data << uint32(curloc);
101 GetPlayer()->m_taxi.AppendTaximaskTo(data, GetPlayer()->isTaxiCheater());
102 SendPacket(&data);
103
104 LOG_DEBUG("network", "WORLD: Sent SMSG_SHOWTAXINODES");
105
106 GetPlayer()->SetTaxiCheater(lastTaxiCheaterState);
107}
@ SMSG_SHOWTAXINODES
Definition: Opcodes.h:455
bool isTaxiCheater() const
Definition: Player.h:1162
void AppendTaximaskTo(ByteBuffer &data, bool all)
Definition: PlayerTaxi.cpp:116

References PlayerTaxi::AppendTaximaskTo(), Object::GetEntry(), Object::GetGUID(), WorldLocation::GetMapId(), GetPlayer(), Position::GetPositionX(), Position::GetPositionY(), Position::GetPositionZ(), GetTeamId(), Player::isTaxiCheater(), LOG_DEBUG, Player::m_taxi, SendPacket(), Player::SetTaxiCheater(), SMSG_SHOWTAXINODES, and sObjectMgr.

Referenced by HandleTaxiQueryAvailableNodes(), and Player::OnGossipSelect().

◆ SendTaxiStatus()

void WorldSession::SendTaxiStatus ( ObjectGuid  guid)
36{
37 Player* const player = GetPlayer();
38 Creature* unit = ObjectAccessor::GetCreature(*player, guid);
39 if (!unit || unit->IsHostileTo(player) || !unit->HasNpcFlag(UNIT_NPC_FLAG_FLIGHTMASTER))
40 {
41 LOG_DEBUG("network", "WorldSession::SendTaxiStatus - Unit ({}) not found.", guid.ToString());
42 return;
43 }
44
45 // find taxi node
46 uint32 nearest = sObjectMgr->GetNearestTaxiNode(unit->GetPositionX(), unit->GetPositionY(), unit->GetPositionZ(), unit->GetMapId(), player->GetTeamId());
47 if (!nearest)
48 {
49 return;
50 }
51
53 data << guid;
54 data << uint8(player->m_taxi.IsTaximaskNodeKnown(nearest) ? 1 : 0);
55 SendPacket(&data);
56 LOG_DEBUG("network", "WORLD: Sent SMSG_TAXINODE_STATUS");
57}
bool IsTaximaskNodeKnown(uint32 nodeidx) const
Definition: PlayerTaxi.h:35
bool HasNpcFlag(NPCFlags flags) const
Definition: Unit.h:694

References ObjectAccessor::GetCreature(), WorldLocation::GetMapId(), GetPlayer(), Position::GetPositionX(), Position::GetPositionY(), Position::GetPositionZ(), Player::GetTeamId(), Unit::HasNpcFlag(), Unit::IsHostileTo(), PlayerTaxi::IsTaximaskNodeKnown(), LOG_DEBUG, Player::m_taxi, SendPacket(), SMSG_TAXINODE_STATUS, sObjectMgr, ObjectGuid::ToString(), and UNIT_NPC_FLAG_FLIGHTMASTER.

Referenced by HandleTaxiNodeStatusQueryOpcode().

◆ SendTimeSync()

void WorldSession::SendTimeSync ( )
1621{
1624 SendPacket(&data);
1625
1627
1628 // Schedule next sync in 10 sec (except for the 2 first packets, which are spaced by only 5s)
1629 _timeSyncTimer = _timeSyncNextCounter == 0 ? 5000 : 10000;
1631}
@ SMSG_TIME_SYNC_REQ
Definition: Opcodes.h:942

References _pendingTimeSyncRequests, _timeSyncNextCounter, _timeSyncTimer, getMSTime(), SendPacket(), and SMSG_TIME_SYNC_REQ.

Referenced by Player::SendInitialPacketsAfterAddToMap(), and Update().

◆ SendTradeStatus()

void WorldSession::SendTradeStatus ( TradeStatus  status)
34{
35 WorldPacket data;
36
37 switch (status)
38 {
40 data.Initialize(SMSG_TRADE_STATUS, 4 + 8);
41 data << uint32(status);
42 data << uint64(0);
43 break;
45 data.Initialize(SMSG_TRADE_STATUS, 4 + 4);
46 data << uint32(status);
47 data << uint32(0); // added in 2.4.0
48 break;
50 data.Initialize(SMSG_TRADE_STATUS, 4 + 4 + 1 + 4);
51 data << uint32(status);
52 data << uint32(0);
53 data << uint8(0);
54 data << uint32(0);
55 break;
58 data.Initialize(SMSG_TRADE_STATUS, 4 + 1);
59 data << uint32(status);
60 data << uint8(0);
61 break;
62 default:
64 data << uint32(status);
65 break;
66 }
67
68 SendPacket(&data);
69}
@ TRADE_STATUS_ONLY_CONJURED
Definition: SharedDefines.h:3572

References WorldPacket::Initialize(), SendPacket(), SMSG_TRADE_STATUS, TRADE_STATUS_BEGIN_TRADE, TRADE_STATUS_CLOSE_WINDOW, TRADE_STATUS_NOT_ELIGIBLE, TRADE_STATUS_ONLY_CONJURED, and TRADE_STATUS_OPEN_WINDOW.

Referenced by HandleAcceptTradeOpcode(), HandleBeginTradeOpcode(), HandleInitiateTradeOpcode(), HandleSetTradeItemOpcode(), SendCancelTrade(), TradeData::SetAccepted(), and TradeData::SetMoney().

◆ SendTrainerList() [1/2]

◆ SendTrainerList() [2/2]

void WorldSession::SendTrainerList ( ObjectGuid  guid,
std::string const &  strTitle 
)
94{
95 LOG_DEBUG("network", "WORLD: SendTrainerList");
96
98 if (!unit)
99 {
100 LOG_DEBUG("network", "WORLD: SendTrainerList - Unit ({}) not found or you can not interact with him.", guid.ToString());
101 return;
102 }
103
104 // remove fake death
105 if (GetPlayer()->HasUnitState(UNIT_STATE_DIED))
107
108 CreatureTemplate const* ci = unit->GetCreatureTemplate();
109
110 if (!ci)
111 {
112 LOG_DEBUG("network", "WORLD: SendTrainerList - ({}) NO CREATUREINFO!", guid.ToString());
113 return;
114 }
115
116 TrainerSpellData const* trainer_spells = unit->GetTrainerSpells();
117 if (!trainer_spells)
118 {
119 LOG_DEBUG("network", "WORLD: SendTrainerList - Training spells not found for creature ({})", guid.ToString());
120 return;
121 }
122
123 WorldPacket data(SMSG_TRAINER_LIST, 8 + 4 + 4 + trainer_spells->spellList.size() * 38 + strTitle.size() + 1);
124 data << guid;
125 data << uint32(trainer_spells->trainerType);
126
127 std::size_t count_pos = data.wpos();
128 data << uint32(trainer_spells->spellList.size());
129
130 // reputation discount
131 float fDiscountMod = _player->GetReputationPriceDiscount(unit);
132 bool can_learn_primary_prof = GetPlayer()->GetFreePrimaryProfessionPoints() > 0;
133
134 uint32 count = 0;
135 for (TrainerSpellMap::const_iterator itr = trainer_spells->spellList.begin(); itr != trainer_spells->spellList.end(); ++itr)
136 {
137 TrainerSpell const* tSpell = &itr->second;
138
139 bool valid = true;
140 bool primary_prof_first_rank = false;
141 for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
142 {
143 if (!tSpell->learnedSpell[i])
144 continue;
146 {
147 valid = false;
148 break;
149 }
150 SpellInfo const* learnedSpellInfo = sSpellMgr->GetSpellInfo(tSpell->learnedSpell[i]);
151 if (learnedSpellInfo && learnedSpellInfo->IsPrimaryProfessionFirstRank())
152 primary_prof_first_rank = true;
153 }
154
155 if (!valid)
156 continue;
157
158 if (tSpell->reqSpell && !_player->HasSpell(tSpell->reqSpell))
159 {
160 continue;
161 }
162
164
165 data << uint32(tSpell->spell); // learned spell (or cast-spell in profession case)
166 data << uint8(state == TRAINER_SPELL_GREEN_DISABLED ? TRAINER_SPELL_GREEN : state);
167 data << uint32(std::floor(tSpell->spellCost * fDiscountMod));
168
169 data << uint32(primary_prof_first_rank && can_learn_primary_prof ? 1 : 0);
170 // primary prof. learn confirmation dialog
171 data << uint32(primary_prof_first_rank ? 1 : 0); // must be equal prev. field to have learn button in enabled state
172 data << uint8(tSpell->reqLevel);
173 data << uint32(tSpell->reqSkill);
174 data << uint32(tSpell->reqSkillValue);
175 //prev + req or req + 0
176 uint8 maxReq = 0;
177 for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
178 {
179 if (!tSpell->learnedSpell[i])
180 continue;
181 if (uint32 prevSpellId = sSpellMgr->GetPrevSpellInChain(tSpell->learnedSpell[i]))
182 {
183 data << uint32(prevSpellId);
184 ++maxReq;
185 }
186 if (maxReq == 3)
187 break;
188 SpellsRequiringSpellMapBounds spellsRequired = sSpellMgr->GetSpellsRequiredForSpellBounds(tSpell->learnedSpell[i]);
189 for (SpellsRequiringSpellMap::const_iterator itr2 = spellsRequired.first; itr2 != spellsRequired.second && maxReq < 3; ++itr2)
190 {
191 data << uint32(itr2->second);
192 ++maxReq;
193 }
194 if (maxReq == 3)
195 break;
196 }
197 while (maxReq < 3)
198 {
199 data << uint32(0);
200 ++maxReq;
201 }
202
203 ++count;
204 }
205
206 data << strTitle;
207
208 data.put<uint32>(count_pos, count);
209 SendPacket(&data);
210}
TrainerSpellState
Definition: Player.h:212
@ TRAINER_SPELL_GREEN_DISABLED
Definition: Player.h:216
std::pair< SpellsRequiringSpellMap::const_iterator, SpellsRequiringSpellMap::const_iterator > SpellsRequiringSpellMapBounds
Definition: SpellMgr.h:570
@ SMSG_TRAINER_LIST
Definition: Opcodes.h:463
uint32 reqSkillValue
Definition: CreatureData.h:518
uint32 learnedSpell[3]
Definition: CreatureData.h:520
uint32 reqSkill
Definition: CreatureData.h:517
uint32 reqLevel
Definition: CreatureData.h:519
TrainerSpellMap spellList
Definition: CreatureData.h:534
uint32 trainerType
Definition: CreatureData.h:535
bool IsSpellFitByClassAndRace(uint32 spell_id) const
Definition: Player.cpp:12356
uint32 GetFreePrimaryProfessionPoints() const
Definition: Player.h:1754
bool IsPrimaryProfessionFirstRank() const
Definition: SpellInfo.cpp:982

References _player, Creature::GetCreatureTemplate(), Player::GetFreePrimaryProfessionPoints(), Player::GetNPCIfCanInteractWith(), GetPlayer(), Player::GetReputationPriceDiscount(), Creature::GetTrainerSpells(), Player::GetTrainerSpellState(), Player::HasSpell(), SpellInfo::IsPrimaryProfessionFirstRank(), Player::IsSpellFitByClassAndRace(), TrainerSpell::learnedSpell, LOG_DEBUG, MAX_SPELL_EFFECTS, ByteBuffer::put(), Unit::RemoveAurasByType(), TrainerSpell::reqLevel, TrainerSpell::reqSkill, TrainerSpell::reqSkillValue, TrainerSpell::reqSpell, SendPacket(), SMSG_TRAINER_LIST, TrainerSpell::spell, SPELL_AURA_FEIGN_DEATH, TrainerSpell::spellCost, TrainerSpellData::spellList, sSpellMgr, ObjectGuid::ToString(), TRAINER_SPELL_GREEN, TRAINER_SPELL_GREEN_DISABLED, TrainerSpellData::trainerType, UNIT_NPC_FLAG_TRAINER, UNIT_STATE_DIED, and ByteBuffer::wpos().

◆ SendTutorialsData()

void WorldSession::SendTutorialsData ( )
933{
935 for (uint8 i = 0; i < MAX_ACCOUNT_TUTORIAL_VALUES; ++i)
936 data << m_Tutorials[i];
937 SendPacket(&data);
938}
@ SMSG_TUTORIAL_FLAGS
Definition: Opcodes.h:283

References m_Tutorials, MAX_ACCOUNT_TUTORIAL_VALUES, SendPacket(), and SMSG_TUTORIAL_FLAGS.

Referenced by InitializeSessionCallback().

◆ SendUpdateTrade()

void WorldSession::SendUpdateTrade ( bool  trader_data = true)
84{
85 TradeData* view_trade = trader_data ? _player->GetTradeData()->GetTraderData() : _player->GetTradeData();
86
87 WorldPacket data(SMSG_TRADE_STATUS_EXTENDED, 1 + 4 + 4 + 4 + 4 + 4 + 7 * (1 + 4 + 4 + 4 + 4 + 8 + 4 + 4 + 4 + 4 + 8 + 4 + 4 + 4 + 4 + 4 + 4));
88 data << uint8(trader_data); // 1 means traders data, 0 means own
89 data << uint32(0); // added in 2.4.0, this value must be equal to value from TRADE_STATUS_OPEN_WINDOW status packet (different value for different players to block multiple trades?)
90 data << uint32(TRADE_SLOT_COUNT); // trade slots count/number?, = next field in most cases
91 data << uint32(TRADE_SLOT_COUNT); // trade slots count/number?, = prev field in most cases
92 data << uint32(view_trade->GetMoney()); // trader gold
93 data << uint32(view_trade->GetSpell()); // spell casted on lowest slot item
94
95 for (uint8 i = 0; i < TRADE_SLOT_COUNT; ++i)
96 {
97 data << uint8(i); // trade slot number, if not specified, then end of packet
98
99 if (Item* item = view_trade->GetItem(TradeSlots(i)))
100 {
101 data << uint32(item->GetTemplate()->ItemId); // entry
102 data << uint32(item->GetTemplate()->DisplayInfoID);// display id
103 data << uint32(item->GetCount()); // stack count
104 // wrapped: hide stats but show giftcreator name
105 data << uint32(item->IsWrapped() ? 1 : 0);
106 data << item->GetGuidValue(ITEM_FIELD_GIFTCREATOR);
107 // perm. enchantment and gems
108 data << uint32(item->GetEnchantmentId(PERM_ENCHANTMENT_SLOT));
109 for (uint32 enchant_slot = SOCK_ENCHANTMENT_SLOT; enchant_slot < SOCK_ENCHANTMENT_SLOT + MAX_GEM_SOCKETS; ++enchant_slot)
110 data << uint32(item->GetEnchantmentId(EnchantmentSlot(enchant_slot)));
111 // creator
112 data << item->GetGuidValue(ITEM_FIELD_CREATOR);
113 data << uint32(item->GetSpellCharges()); // charges
114 data << uint32(item->GetItemSuffixFactor()); // SuffixFactor
115 data << int32(item->GetItemRandomPropertyId()); // random properties id
116 data << uint32(item->GetTemplate()->LockID); // lock id
117 // max durability
118 data << uint32(item->GetUInt32Value(ITEM_FIELD_MAXDURABILITY));
119 // durability
120 data << uint32(item->GetUInt32Value(ITEM_FIELD_DURABILITY));
121 }
122 else
123 {
124 for (uint8 j = 0; j < 18; ++j)
125 data << uint32(0);
126 }
127 }
128 SendPacket(&data);
129}
@ PERM_ENCHANTMENT_SLOT
Definition: Item.h:169
@ SMSG_TRADE_STATUS_EXTENDED
Definition: Opcodes.h:319
TradeData * GetTraderData() const
Definition: TradeData.cpp:21

References _player, TradeData::GetItem(), TradeData::GetMoney(), TradeData::GetSpell(), Player::GetTradeData(), TradeData::GetTraderData(), ITEM_FIELD_CREATOR, ITEM_FIELD_DURABILITY, ITEM_FIELD_GIFTCREATOR, ITEM_FIELD_MAXDURABILITY, MAX_GEM_SOCKETS, PERM_ENCHANTMENT_SLOT, SendPacket(), SMSG_TRADE_STATUS_EXTENDED, SOCK_ENCHANTMENT_SLOT, and TRADE_SLOT_COUNT.

Referenced by TradeData::Update().

◆ SendWrongFactionNotice()

void WorldSession::SendWrongFactionNotice ( )
838{
840 SendPacket(&data);
841}
@ SMSG_CHAT_WRONG_FACTION
Definition: Opcodes.h:567

References SendPacket(), and SMSG_CHAT_WRONG_FACTION.

Referenced by HandleMessagechatOpcode().

◆ SetAccountData()

void WorldSession::SetAccountData ( AccountDataType  type,
time_t  tm,
std::string const &  data 
)
876{
877 uint32 id = 0;
879 if ((1 << type) & GLOBAL_CACHE_MASK)
880 {
881 id = GetAccountId();
882 index = CHAR_REP_ACCOUNT_DATA;
883 }
884 else
885 {
886 // _player can be nullptr and packet received after logout but m_GUID still store correct guid
887 if (!m_GUIDLow)
888 return;
889
890 id = m_GUIDLow;
892 }
893
894 CharacterDatabasePreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(index);
895 stmt->SetData(0, id);
896 stmt->SetData(1, type);
897 stmt->SetData(2, uint32(tm));
898 stmt->SetData(3, data);
899 CharacterDatabase.Execute(stmt);
900
901 m_accountData[type].Time = tm;
902 m_accountData[type].Data = data;
903}
CharacterDatabaseStatements
Definition: CharacterDatabase.h:24
@ CHAR_REP_PLAYER_ACCOUNT_DATA
Definition: CharacterDatabase.h:202
@ CHAR_REP_ACCOUNT_DATA
Definition: CharacterDatabase.h:199

References CHAR_REP_ACCOUNT_DATA, CHAR_REP_PLAYER_ACCOUNT_DATA, CharacterDatabase, AccountData::Data, GetAccountId(), GLOBAL_CACHE_MASK, m_accountData, m_GUIDLow, PreparedStatementBase::SetData(), and AccountData::Time.

Referenced by HandleUpdateAccountData().

◆ SetCalendarEventCreationCooldown()

void WorldSession::SetCalendarEventCreationCooldown ( time_t  cooldown)
inline

◆ SetCurrentVendor()

void WorldSession::SetCurrentVendor ( uint32  vendorEntry)
inline
367{ m_currentVendorEntry = vendorEntry; }

References m_currentVendorEntry.

Referenced by SendListInventory().

◆ SetInQueue()

void WorldSession::SetInQueue ( bool  state)
inline

Session in auth.queue currently.

382{ m_inQueue = state; }

References m_inQueue.

Referenced by World::AddQueuedPlayer(), InitializeSessionCallback(), and World::RemoveQueuedPlayer().

◆ SetKicked()

void WorldSession::SetKicked ( bool  val)
inline
1070{ _kicked = val; }

References _kicked.

Referenced by KickPlayer().

◆ SetLatency()

void WorldSession::SetLatency ( uint32  latency)
inline
503{ m_latency = latency; }

References m_latency.

Referenced by WorldSocket::HandlePing().

◆ SetLogoutStartTime()

void WorldSession::SetLogoutStartTime ( time_t  requestTime)
inline

Engage the logout process for the user.

389 {
390 _logoutTime = requestTime;
391 }

References _logoutTime.

Referenced by HandleLogoutCancelOpcode(), HandleLogoutRequestOpcode(), and LogoutPlayer().

◆ SetOfflineTime()

void WorldSession::SetOfflineTime ( uint32  time)
inline
1067{ _offlineTime = time; }

References _offlineTime.

Referenced by World::AddSession_(), and World::UpdateSessions().

◆ SetPlayer()

void WorldSession::SetPlayer ( Player player)
1262{
1263 _player = player;
1264
1265 // set m_GUID that can be used while player loggined and later until m_playerRecentlyLogout not reset
1266 if (_player)
1268}

References _player, ObjectGuid::GetCounter(), Object::GetGUID(), and m_GUIDLow.

Referenced by HandlePlayerLoginFromDB(), HandlePlayerLoginOpcode(), Player::LoadFromDB(), and LogoutPlayer().

◆ SetSecurity()

void WorldSession::SetSecurity ( AccountTypes  security)
inline
370{ _security = security; }

References _security.

◆ SetTotalTime()

void WorldSession::SetTotalTime ( uint32  TotalTime)
inline
375{ m_total_time = TotalTime; }

References m_total_time.

Referenced by Player::Update().

◆ SetTutorialInt()

void WorldSession::SetTutorialInt ( uint8  index,
uint32  value 
)
inline
460 {
461 if (m_Tutorials[index] != value)
462 {
463 m_Tutorials[index] = value;
464 m_TutorialsChanged = true;
465 }
466 }

References m_Tutorials, and m_TutorialsChanged.

Referenced by HandleTutorialClear(), HandleTutorialFlag(), and HandleTutorialReset().

◆ ShouldLogOut()

bool WorldSession::ShouldLogOut ( time_t  currTime) const
inline

Is logout cooldown expired?

395 {
396 return (_logoutTime > 0 && currTime >= _logoutTime + 20);
397 }

References _logoutTime.

Referenced by Update().

◆ Update()

bool WorldSession::Update ( uint32  diff,
PacketFilter updater 
)

Update the WorldSession (triggered by World update)

  • Before we process anything: If necessary, kick the player because the client didn't send anything for too long (or they've been idling in character select)
  • Retrieve packets from the receive queue and call the appropriate handlers not process packets if socket already closed

Delete packet after processing by default

If player didn't log out a while ago, it means packets are being sent while the server does not recognize the client to be in world yet. We will re-add the packets to the bottom of the queue and process them later.

290{
295 m_Socket->CloseSocket();
296
297 if (updater.ProcessUnsafe())
298 UpdateTimeOutTime(diff);
299
301
304 WorldPacket* packet = nullptr;
305
307 bool deletePacket = true;
308 std::vector<WorldPacket*> requeuePackets;
309 uint32 processedPackets = 0;
310 time_t currentTime = GameTime::GetGameTime().count();
311
312 constexpr uint32 MAX_PROCESSED_PACKETS_IN_SAME_WORLDSESSION_UPDATE = 150;
313
314 while (m_Socket && _recvQueue.next(packet, updater))
315 {
316 OpcodeClient opcode = static_cast<OpcodeClient>(packet->GetOpcode());
317 ClientOpcodeHandler const* opHandle = opcodeTable[opcode];
318
319 METRIC_DETAILED_TIMER("worldsession_update_opcode_time", METRIC_TAG("opcode", opHandle->Name));
320 LOG_DEBUG("network", "message id {} ({}) under READ", opcode, opHandle->Name);
321
322 try
323 {
324 switch (opHandle->Status)
325 {
326 case STATUS_LOGGEDIN:
327 if (!_player)
328 {
329 // skip STATUS_LOGGEDIN opcode unexpected errors if player logout sometime ago - this can be network lag delayed packets
333 {
334 requeuePackets.push_back(packet);
335 deletePacket = false;
336
337 LOG_DEBUG("network", "Delaying processing of message with status STATUS_LOGGEDIN: No players in the world for account id {}", GetAccountId());
338 }
339 }
340 else if (_player->IsInWorld())
341 {
342 if (AntiDOS.EvaluateOpcode(*packet, currentTime))
343 {
344 if (!sScriptMgr->CanPacketReceive(this, *packet))
345 {
346 break;
347 }
348
349 opHandle->Call(this, *packet);
350 LogUnprocessedTail(packet);
351 }
352 else
353 processedPackets = MAX_PROCESSED_PACKETS_IN_SAME_WORLDSESSION_UPDATE; // break out of packet processing loop
354 }
355
356 // lag can cause STATUS_LOGGEDIN opcodes to arrive after the player started a transfer
357 break;
359 if (!_player && !m_playerRecentlyLogout) // There's a short delay between _player = null and m_playerRecentlyLogout = true during logout
360 {
361 LogUnexpectedOpcode(packet, "STATUS_LOGGEDIN_OR_RECENTLY_LOGGOUT",
362 "the player has not logged in yet and not recently logout");
363 }
364 else if (AntiDOS.EvaluateOpcode(*packet, currentTime))
365 {
366 // not expected _player or must checked in packet hanlder
367 if (!sScriptMgr->CanPacketReceive(this, *packet))
368 break;
369
370 opHandle->Call(this, *packet);
371 LogUnprocessedTail(packet);
372 }
373 else
374 processedPackets = MAX_PROCESSED_PACKETS_IN_SAME_WORLDSESSION_UPDATE; // break out of packet processing loop
375 break;
376 case STATUS_TRANSFER:
377 if (_player && !_player->IsInWorld() && AntiDOS.EvaluateOpcode(*packet, currentTime))
378 {
379 if (!sScriptMgr->CanPacketReceive(this, *packet))
380 {
381 break;
382 }
383
384 opHandle->Call(this, *packet);
385 LogUnprocessedTail(packet);
386 }
387 else
388 processedPackets = MAX_PROCESSED_PACKETS_IN_SAME_WORLDSESSION_UPDATE; // break out of packet processing loop
389 break;
390 case STATUS_AUTHED:
391 if (m_inQueue) // prevent cheating
392 break;
393
394 // some auth opcodes can be recieved before STATUS_LOGGEDIN_OR_RECENTLY_LOGGOUT opcodes
395 // however when we recieve CMSG_CHAR_ENUM we are surely no longer during the logout process.
396 if (packet->GetOpcode() == CMSG_CHAR_ENUM)
398
399 if (AntiDOS.EvaluateOpcode(*packet, currentTime))
400 {
401 if (!sScriptMgr->CanPacketReceive(this, *packet))
402 {
403 break;
404 }
405
406 opHandle->Call(this, *packet);
407 LogUnprocessedTail(packet);
408 }
409 else
410 processedPackets = MAX_PROCESSED_PACKETS_IN_SAME_WORLDSESSION_UPDATE; // break out of packet processing loop
411 break;
412 case STATUS_NEVER:
413 LOG_ERROR("network.opcode", "Received not allowed opcode {} from {}",
414 GetOpcodeNameForLogging(static_cast<OpcodeClient>(packet->GetOpcode())), GetPlayerInfo());
415 break;
416 case STATUS_UNHANDLED:
417 LOG_DEBUG("network.opcode", "Received not handled opcode {} from {}",
418 GetOpcodeNameForLogging(static_cast<OpcodeClient>(packet->GetOpcode())), GetPlayerInfo());
419 break;
420 }
421 }
423 {
424 LOG_ERROR("network", "{} sent {} with an invalid link:\n{}", GetPlayerInfo(),
425 GetOpcodeNameForLogging(static_cast<OpcodeClient>(packet->GetOpcode())), ihe.GetInvalidValue());
426
428 {
429 KickPlayer("WorldSession::Update Invalid chat link");
430 }
431 }
433 {
434 LOG_ERROR("network", "{} sent {} which illegally contained a hyperlink:\n{}", GetPlayerInfo(),
435 GetOpcodeNameForLogging(static_cast<OpcodeClient>(packet->GetOpcode())), ihe.GetInvalidValue());
436
438 {
439 KickPlayer("WorldSession::Update Illegal chat link");
440 }
441 }
443 {
444 LOG_ERROR("network", "PacketArrayMaxCapacityException: {} while parsing {} from {}.",
445 pamce.what(), GetOpcodeNameForLogging(static_cast<OpcodeClient>(packet->GetOpcode())), GetPlayerInfo());
446 }
447 catch (ByteBufferException const&)
448 {
449 LOG_ERROR("network", "WorldSession::Update ByteBufferException occured while parsing a packet (opcode: {}) from client {}, accountid={}. Skipped packet.", packet->GetOpcode(), GetRemoteAddress(), GetAccountId());
450 if (sLog->ShouldLog("network", LogLevel::LOG_LEVEL_DEBUG))
451 {
452 LOG_DEBUG("network", "Dumping error causing packet:");
453 packet->hexlike();
454 }
455 }
456
457 if (deletePacket)
458 delete packet;
459
460 deletePacket = true;
461
462 processedPackets++;
463
464 //process only a max amout of packets in 1 Update() call.
465 //Any leftover will be processed in next update
466 if (processedPackets > MAX_PROCESSED_PACKETS_IN_SAME_WORLDSESSION_UPDATE)
467 break;
468 }
469
470 _recvQueue.readd(requeuePackets.begin(), requeuePackets.end());
471
472 METRIC_VALUE("processed_packets", processedPackets);
473 METRIC_VALUE("addon_messages", _addonMessageReceiveCount.load());
475
476 if (!updater.ProcessUnsafe()) // <=> updater is of type MapSessionFilter
477 {
478 // Send time sync packet every 10s.
479 if (_timeSyncTimer > 0)
480 {
481 if (diff >= _timeSyncTimer)
482 {
483 SendTimeSync();
484 }
485 else
486 {
487 _timeSyncTimer -= diff;
488 }
489 }
490 }
491
493
494 //check if we are safe to proceed with logout
495 //logout procedure should happen only in World::UpdateSessions() method!!!
496 if (updater.ProcessUnsafe())
497 {
498 if (m_Socket && m_Socket->IsOpen() && _warden)
499 {
500 _warden->Update(diff);
501 }
502
503 if (ShouldLogOut(currentTime) && !m_playerLoading)
504 {
505 LogoutPlayer(true);
506 }
507
508 if (m_Socket && !m_Socket->IsOpen())
509 {
510 if (GetPlayer() && _warden)
511 _warden->Update(diff);
512
513 m_Socket = nullptr;
514 }
515
516 if (!m_Socket)
517 {
518 return false; //Will remove this session from the world session map
519 }
520 }
521
522 return true;
523}
#define METRIC_DETAILED_TIMER(category,...)
Definition: Metric.h:219
#define METRIC_VALUE(category, value,...)
Definition: Metric.h:193
#define METRIC_TAG(name, value)
Definition: Metric.h:159
@ CONFIG_CLOSE_IDLE_CONNECTIONS
Definition: IWorld.h:156
@ STATUS_AUTHED
Definition: AuthSession.h:42
char const * Name
Definition: Opcodes.h:1380
OpcodeTable opcodeTable
Definition: Opcodes.cpp:51
SessionStatus Status
Definition: Opcodes.h:1381
virtual void Call(WorldSession *session, WorldPacket &packet) const =0
@ CMSG_CHAR_ENUM
Definition: Opcodes.h:85
@ STATUS_LOGGEDIN
Definition: Opcodes.h:1357
@ STATUS_LOGGEDIN_OR_RECENTLY_LOGGOUT
Definition: Opcodes.h:1359
@ STATUS_TRANSFER
Definition: Opcodes.h:1358
@ STATUS_NEVER
Definition: Opcodes.h:1360
@ STATUS_UNHANDLED
Definition: Opcodes.h:1361
void readd(Iterator begin, Iterator end)
Adds items back to front of the queue.
Definition: LockedQueue.h:56
std::string const & GetInvalidValue() const
Definition: PacketUtilities.h:33
Definition: PacketUtilities.h:46
Definition: PacketUtilities.h:52
Definition: PacketUtilities.h:110
Definition: Opcodes.h:1385
virtual bool ProcessUnsafe() const
Definition: WorldSession.h:237
void SendTimeSync()
Definition: WorldSession.cpp:1620
void UpdateTimeOutTime(uint32 diff)
Definition: WorldSession.h:506
void LogUnexpectedOpcode(WorldPacket *packet, char const *status, const char *reason)
Logging helper for unexpected opcodes.
Definition: WorldSession.cpp:270
void LogUnprocessedTail(WorldPacket *packet)
Logging helper for unexpected opcodes.
Definition: WorldSession.cpp:277
void ProcessQueryCallbacks()
Definition: WorldSession.cpp:1270
void HandleTeleportTimeout(bool updateInSessions)
Definition: WorldSession.cpp:542
bool ShouldLogOut(time_t currTime) const
Is logout cooldown expired?
Definition: WorldSession.h:394
bool IsConnectionIdle() const
Definition: WorldSession.h:520
bool EvaluateOpcode(WorldPacket &p, time_t time) const
Definition: WorldSession.cpp:1307
char const * what() const noexcept override
Definition: ByteBuffer.h:36

References _addonMessageReceiveCount, _player, _recvQueue, _timeSyncTimer, _warden, AntiDOS, ClientOpcodeHandler::Call(), CMSG_CHAR_ENUM, CONFIG_CHAT_STRICT_LINK_CHECKING_KICK, CONFIG_CLOSE_IDLE_CONNECTIONS, WorldSession::DosProtection::EvaluateOpcode(), GetAccountId(), GameTime::GetGameTime(), WorldPackets::InvalidStringValueException::GetInvalidValue(), WorldPacket::GetOpcode(), GetOpcodeNameForLogging(), GetPlayer(), GetPlayerInfo(), GetRemoteAddress(), HandleTeleportTimeout(), ByteBuffer::hexlike(), IsConnectionIdle(), Object::IsInWorld(), KickPlayer(), LOG_DEBUG, LOG_ERROR, LogoutPlayer(), LogUnexpectedOpcode(), LogUnprocessedTail(), m_inQueue, m_playerLoading, m_playerRecentlyLogout, m_Socket, METRIC_DETAILED_TIMER, METRIC_TAG, METRIC_VALUE, OpcodeHandler::Name, LockedQueue< T, StorageType >::next(), opcodeTable, ProcessQueryCallbacks(), PacketFilter::ProcessUnsafe(), LockedQueue< T, StorageType >::readd(), SendTimeSync(), ShouldLogOut(), sLog, sScriptMgr, OpcodeHandler::Status, STATUS_AUTHED, STATUS_LOGGEDIN, STATUS_LOGGEDIN_OR_RECENTLY_LOGGOUT, STATUS_NEVER, STATUS_TRANSFER, STATUS_UNHANDLED, sWorld, UpdateTimeOutTime(), and ByteBufferException::what().

Referenced by Map::Update(), and World::UpdateSessions().

◆ UpdateTimeOutTime()

void WorldSession::UpdateTimeOutTime ( uint32  diff)
inline
507 {
508 if (time_t(diff) > m_timeOutTime)
509 m_timeOutTime = 0;
510 else
511 m_timeOutTime -= diff;
512 }

References m_timeOutTime.

Referenced by Update().

◆ ValidateHyperlinksAndMaybeKick()

bool WorldSession::ValidateHyperlinksAndMaybeKick ( std::string_view  str)
766{
768 return true;
769
770 LOG_ERROR("network", "Player {} {} sent a message with an invalid link:\n%.*s", GetPlayer()->GetName(),
771 GetPlayer()->GetGUID().ToString(), STRING_VIEW_FMT_ARG(str));
772
774 KickPlayer("WorldSession::ValidateHyperlinksAndMaybeKick Invalid chat link");
775
776 return false;
777}
bool AC_GAME_API CheckAllLinks(std::string_view str)
Definition: Hyperlinks.cpp:377

References Acore::Hyperlinks::CheckAllLinks(), CONFIG_CHAT_STRICT_LINK_CHECKING_KICK, GetPlayer(), KickPlayer(), LOG_ERROR, STRING_VIEW_FMT_ARG, and sWorld.

Referenced by HandleGMSurveySubmit(), HandleGMTicketCreateOpcode(), HandleGMTicketUpdateOpcode(), and HandleMessagechatOpcode().

◆ WriteMovementInfo()

void WorldSession::WriteMovementInfo ( WorldPacket data,
MovementInfo mi 
)
1074{
1075 *data << mi->guid.WriteAsPacked();
1076
1077 *data << mi->flags;
1078 *data << mi->flags2;
1079 *data << mi->time;
1080 *data << mi->pos.PositionXYZOStream();
1081
1083 {
1084 *data << mi->transport.guid.WriteAsPacked();
1085
1086 *data << mi->transport.pos.PositionXYZOStream();
1087 *data << mi->transport.time;
1088 *data << mi->transport.seat;
1089
1091 *data << mi->transport.time2;
1092 }
1093
1095 *data << mi->pitch;
1096
1097 *data << mi->fallTime;
1098
1100 {
1101 *data << mi->jump.zspeed;
1102 *data << mi->jump.sinAngle;
1103 *data << mi->jump.cosAngle;
1104 *data << mi->jump.xyspeed;
1105 }
1106
1108 *data << mi->splineElevation;
1109}

References MovementInfo::JumpInfo::cosAngle, MovementInfo::fallTime, MovementInfo::flags, MovementInfo::flags2, MovementInfo::guid, MovementInfo::TransportInfo::guid, MovementInfo::HasExtraMovementFlag(), MovementInfo::HasMovementFlag(), MovementInfo::jump, MOVEMENTFLAG2_ALWAYS_ALLOW_PITCHING, MOVEMENTFLAG2_INTERPOLATED_MOVEMENT, MOVEMENTFLAG_FALLING, MOVEMENTFLAG_FLYING, MOVEMENTFLAG_ONTRANSPORT, MOVEMENTFLAG_SPLINE_ELEVATION, MOVEMENTFLAG_SWIMMING, MovementInfo::pitch, MovementInfo::pos, MovementInfo::TransportInfo::pos, Position::PositionXYZOStream(), MovementInfo::TransportInfo::seat, MovementInfo::JumpInfo::sinAngle, MovementInfo::splineElevation, MovementInfo::time, MovementInfo::TransportInfo::time, MovementInfo::TransportInfo::time2, MovementInfo::transport, ObjectGuid::WriteAsPacked(), MovementInfo::JumpInfo::xyspeed, and MovementInfo::JumpInfo::zspeed.

Referenced by HandleMovementOpcodes(), HandleMoveRootAck(), and HandleMoveUnRootAck().

Friends And Related Function Documentation

◆ World

friend class World
friend

Member Data Documentation

◆ _accountId

uint32 WorldSession::_accountId
private

Referenced by GetAccountId().

◆ _accountName

std::string WorldSession::_accountName
private

◆ _addonMessageReceiveCount

std::atomic<uint32> WorldSession::_addonMessageReceiveCount
private

Referenced by HandleMessagechatOpcode(), and Update().

◆ _calendarEventCreationCooldown

time_t WorldSession::_calendarEventCreationCooldown
private

◆ _kicked

bool WorldSession::_kicked
private

Referenced by IsKicked(), SetKicked(), and WorldSession().

◆ _lastAuctionListItemsMSTime

Milliseconds WorldSession::_lastAuctionListItemsMSTime

Referenced by HandleAuctionListItems().

◆ _lastAuctionListOwnerItemsMSTime

Milliseconds WorldSession::_lastAuctionListOwnerItemsMSTime

◆ _legitCharacters

GuidSet WorldSession::_legitCharacters
private

◆ _logoutTime

time_t WorldSession::_logoutTime
private

◆ _offlineTime

uint32 WorldSession::_offlineTime
private

◆ _pendingTimeSyncRequests

std::map<uint32, uint32> WorldSession::_pendingTimeSyncRequests
private

◆ _player

Player* WorldSession::_player
private

Referenced by CanOpenMailBox(), DoLootRelease(), GetPlayer(), GetPlayerInfo(), GetPlayerName(), HandleAcceptGrantLevel(), HandleAcceptTradeOpcode(), HandleAlterAppearance(), HandleAreaSpiritHealerQueryOpcode(), HandleAreaSpiritHealerQueueOpcode(), HandleAreaTriggerOpcode(), HandleArenaTeamAcceptOpcode(), HandleArenaTeamDeclineOpcode(), HandleArenaTeamDisbandOpcode(), HandleArenaTeamLeaderOpcode(), HandleArenaTeamLeaveOpcode(), HandleArenaTeamRemoveOpcode(), HandleAttackSwingOpcode(), HandleAuctionListItems(), HandleAuctionListOwnerItems(), HandleAuctionListOwnerItemsEvent(), HandleAuctionSellItem(), HandleAutoBankItemOpcode(), HandleAutoEquipItemOpcode(), HandleAutoEquipItemSlotOpcode(), HandleAutoStoreBagItemOpcode(), HandleAutoStoreBankItemOpcode(), HandleAutostoreLootItemOpcode(), HandleBattlefieldLeaveOpcode(), HandleBattlefieldListOpcode(), HandleBattleFieldPortOpcode(), HandleBattlefieldStatusOpcode(), HandleBattlegroundPlayerPositionsOpcode(), HandleBattlemasterHelloOpcode(), HandleBattlemasterJoinArena(), HandleBattlemasterJoinOpcode(), HandleBeginTradeOpcode(), HandleBfEntryInviteResponse(), HandleBfExitRequest(), HandleBfQueueInviteResponse(), HandleBusyTradeOpcode(), HandleBuybackItem(), HandleBuyBankSlotOpcode(), HandleBuyItemInSlotOpcode(), HandleBuyStableSlot(), HandleCalendarAddEvent(), HandleCalendarArenaTeam(), HandleCalendarComplain(), HandleCalendarCopyEvent(), HandleCalendarEventInvite(), HandleCalendarEventModeratorStatus(), HandleCalendarEventRemoveInvite(), HandleCalendarEventRsvp(), HandleCalendarEventSignup(), HandleCalendarEventStatus(), HandleCalendarGetCalendar(), HandleCalendarGetEvent(), HandleCalendarGetNumPending(), HandleCalendarGuildFilter(), HandleCalendarRemoveEvent(), HandleCalendarUpdateEvent(), HandleCancelAuraOpcode(), HandleCancelAutoRepeatSpellOpcode(), HandleCancelCastOpcode(), HandleCancelChanneling(), HandleCancelMountAuraOpcode(), HandleCancelTradeOpcode(), HandleCastSpellOpcode(), HandleChatIgnoredOpcode(), HandleClearTradeItemOpcode(), HandleContactListOpcode(), HandleCorpseQueryOpcode(), HandleDelFriendOpcode(), HandleDelIgnoreOpcode(), HandleDestroyItemOpcode(), HandleDismissControlledVehicle(), HandleDismissCritter(), HandleEjectPassenger(), HandleEmoteOpcode(), HandleEnterPlayerVehicle(), HandleEquipmentSetDelete(), HandleEquipmentSetSave(), HandleEquipmentSetUse(), HandleFarSightOpcode(), HandleForceSpeedChangeAck(), HandleGameobjectReportUse(), HandleGetMailList(), HandleGossipHelloOpcode(), HandleGossipSelectOptionOpcode(), HandleGrantLevel(), HandleGroupDisbandOpcode(), HandleGroupRaidConvertOpcode(), HandleHearthAndResurrect(), HandleIgnoreTradeOpcode(), HandleInitiateTradeOpcode(), HandleInspectHonorStatsOpcode(), HandleInspectOpcode(), HandleInstanceLockResponse(), HandleItemRefund(), HandleItemRefundInfoRequest(), HandleItemTextQuery(), HandleLearnPreviewTalents(), HandleLearnPreviewTalentsPet(), HandleLearnTalentOpcode(), HandleLootMasterGiveOpcode(), HandleMailCreateTextItem(), HandleMailDelete(), HandleMailMarkAsRead(), HandleMailReturnToSender(), HandleMailTakeItem(), HandleMailTakeMoney(), HandleMessagechatOpcode(), HandleMirrorImageDataRequest(), HandleMoveKnockBackAck(), HandleMovementOpcodes(), HandleMoveNotActiveMover(), HandleMoveRootAck(), HandleMoveSetCanFlyAckOpcode(), HandleMoveTeleportAck(), HandleMoveUnRootAck(), HandleMoveWorldportAck(), HandleOfferPetitionOpcode(), HandleOpenItemOpcode(), HandlePetAbandon(), HandlePetAction(), HandlePetActionHelper(), HandlePetCancelAuraOpcode(), HandlePetCastSpellOpcode(), HandlePetitionBuyOpcode(), HandlePetitionDeclineOpcode(), HandlePetitionRenameOpcode(), HandlePetitionShowSignOpcode(), HandlePetitionSignOpcode(), HandlePetLearnTalent(), HandlePetRename(), HandlePetSetAction(), HandlePetSpellAutocastOpcode(), HandlePetStopAttack(), HandlePlayedTime(), HandlePlayerLoginFromDB(), HandlePushQuestToParty(), HandlePVPLogDataOpcode(), HandleQueryInspectAchievements(), HandleQueryNextMailTime(), HandleQueryQuestsCompleted(), HandleQuestConfirmAccept(), HandleQuestgiverAcceptQuestOpcode(), HandleQuestgiverCancel(), HandleQuestgiverChooseRewardOpcode(), HandleQuestgiverCompleteQuest(), HandleQuestgiverHelloOpcode(), HandleQuestgiverQueryQuestOpcode(), HandleQuestgiverRequestRewardOpcode(), HandleQuestgiverStatusMultipleQuery(), HandleQuestgiverStatusQueryOpcode(), HandleQuestLogRemoveQuest(), HandleQuestPOIQuery(), HandleQuestPushResult(), HandleQuestQueryOpcode(), HandleRaidReadyCheckOpcode(), HandleRaidTargetUpdateOpcode(), HandleReadItem(), HandleReclaimCorpseOpcode(), HandleRemoveGlyph(), HandleRepairItemOpcode(), HandleReportPvPAFK(), HandleRequestAccountData(), HandleRequestPartyMemberStatsOpcode(), HandleRequestPetInfo(), HandleRequestRaidInfoOpcode(), HandleResetInstancesOpcode(), HandleSelfResOpcode(), HandleSellItemOpcode(), HandleSendMail(), HandleSetActionButtonOpcode(), HandleSetActiveMoverOpcode(), HandleSetAmmoOpcode(), HandleSetContactNotesOpcode(), HandleSetDungeonDifficultyOpcode(), HandleSetFactionInactiveOpcode(), HandleSetRaidDifficultyOpcode(), HandleSetSelectionOpcode(), HandleSetSheathedOpcode(), HandleSetTaxiBenchmarkOpcode(), HandleSetTradeGoldOpcode(), HandleSetTradeItemOpcode(), HandleShowingCloakOpcode(), HandleShowingHelmOpcode(), HandleSocketOpcode(), HandleSpellClick(), HandleSplitItemOpcode(), HandleStablePet(), HandleStableSwapPet(), HandleStandStateChangeOpcode(), HandleSummonResponseOpcode(), HandleSwapInvItemOpcode(), HandleSwapItem(), HandleTalentWipeConfirmOpcode(), HandleTextEmoteOpcode(), HandleTotemDestroyed(), HandleTrainerBuySpellOpcode(), HandleTurnInPetitionOpcode(), HandleUnacceptTradeOpcode(), HandleUnstablePet(), HandleUpdateMissileTrajectory(), HandleUpdateProjectilePosition(), HandleUseItemOpcode(), HandleWhoOpcode(), HandleWrapItemOpcode(), KickPlayer(), LogoutPlayer(), moveItems(), SendBattleGroundList(), SendBfEntered(), SendBindPoint(), SendListInventory(), SendPetitionShowList(), SendPetNameQuery(), SendSpiritResurrect(), SendTrainerList(), SendUpdateTrade(), SetPlayer(), Update(), and ~WorldSession().

◆ _queryHolderProcessor

AsyncCallbackProcessor<SQLQueryHolderCallback> WorldSession::_queryHolderProcessor
private

◆ _queryProcessor

◆ _recvQueue

LockedQueue<WorldPacket*> WorldSession::_recvQueue
private

Referenced by QueuePacket(), Update(), and ~WorldSession().

◆ _security

AccountTypes WorldSession::_security
private

Referenced by GetSecurity(), and SetSecurity().

◆ _skipQueue

bool WorldSession::_skipQueue
private

Referenced by CanSkipQueue().

◆ _timeSyncClockDelta

int64 WorldSession::_timeSyncClockDelta
private

◆ _timeSyncClockDeltaQueue

CircularBuffer<std::pair<int64, uint32> > WorldSession::_timeSyncClockDeltaQueue
private

◆ _timeSyncNextCounter

uint32 WorldSession::_timeSyncNextCounter
private

◆ _timeSyncTimer

uint32 WorldSession::_timeSyncTimer
private

Referenced by SendTimeSync(), Update(), and WorldSession().

◆ _transactionCallbacks

AsyncCallbackProcessor<TransactionCallback> WorldSession::_transactionCallbacks
private

◆ _warden

std::unique_ptr<Warden> WorldSession::_warden
private

◆ AntiDOS

class WorldSession::DosProtection WorldSession::AntiDOS
protected

Referenced by Update().

◆ isRecruiter

bool WorldSession::isRecruiter
private

Referenced by IsARecruiter().

◆ m_accountData

AccountData WorldSession::m_accountData[NUM_ACCOUNT_DATA_TYPES]
private

◆ m_addonsList

AddonsList WorldSession::m_addonsList
private

Referenced by ReadAddonsInfo(), and SendAddonsInfo().

◆ m_Address

std::string WorldSession::m_Address
private

Referenced by GetRemoteAddress(), and WorldSession().

◆ m_currentBankerGUID

ObjectGuid WorldSession::m_currentBankerGUID
private

◆ m_currentVendorEntry

uint32 WorldSession::m_currentVendorEntry
private

◆ m_expansion

uint8 WorldSession::m_expansion
private

Referenced by Expansion().

◆ m_GUIDLow

ObjectGuid::LowType WorldSession::m_GUIDLow
private

Referenced by SetAccountData(), and SetPlayer().

◆ m_inQueue

bool WorldSession::m_inQueue
private

◆ m_latency

std::atomic<uint32> WorldSession::m_latency
private

Referenced by GetLatency(), and SetLatency().

◆ m_muteTime

◆ m_playerLoading

◆ m_playerLogout

bool WorldSession::m_playerLogout
private

◆ m_playerRecentlyLogout

bool WorldSession::m_playerRecentlyLogout
private

◆ m_playerSave

bool WorldSession::m_playerSave
private

◆ m_sessionDbcLocale

LocaleConstant WorldSession::m_sessionDbcLocale
private

Referenced by GetSessionDbcLocale().

◆ m_sessionDbLocaleIndex

LocaleConstant WorldSession::m_sessionDbLocaleIndex
private

Referenced by GetSessionDbLocaleIndex().

◆ m_Socket

◆ m_timeOutTime

std::atomic<time_t> WorldSession::m_timeOutTime

◆ m_total_time

uint32 WorldSession::m_total_time
private

Referenced by GetTotalTime(), and SetTotalTime().

◆ m_Tutorials

◆ m_TutorialsChanged

bool WorldSession::m_TutorialsChanged
private

◆ recruiterId

uint32 WorldSession::recruiterId
private

Referenced by GetRecruiterId().